Back to Copilotkit

Error Observability Connectors

showcase/shell-docs/src/content/docs/troubleshooting/observability-connectors.mdx

1.57.08.2 KB
Original Source

CopilotKit Premium provides production-grade error observability with the observability solution of your choice via the onError hook on CopilotKitProvider. This feature requires a publicLicenseKey or publicApiKey and provides structured error events you can forward to your monitoring and analytics systems. See Observability for a complete description of all Observability features.

Quick Setup

tsx
import { CopilotKitProvider } from "@copilotkit/react-core/v2";

export default function App() {
  return (
    <CopilotKitProvider
      runtimeUrl="<your-runtime-url>"
      publicApiKey="ck_pub_your_key" // [!code highlight] - Use publicApiKey for Copilot Cloud
      // OR
      publicLicenseKey="ck_pub_your_key" // [!code highlight] - Use publicLicenseKey for self-hosted
      onError={({ error, code, context }) => {
        // [!code highlight]
        // Send to your monitoring/analytics service
        console.error("CopilotKit Error:", { error, code, context });
        analytics.track("copilotkit_error", {
          code,
          message: error.message,
          context,
        });
      }} // [!code highlight]
      showDevConsole={false}
    >
    </CopilotKitProvider>
  );
}
<Callout type="info"> **Key Configuration**: - Use `publicApiKey` when using Copilot Cloud - Use `publicLicenseKey` when self-hosting CopilotKit - Both keys provide the same observability features </Callout>

Getting Your License or API Key

You can get either type of key from cloud.copilotkit.ai. Sign up for the Developer plan for free if you aren't already signed up.

  1. For Copilot Cloud hosting: Login to CopilotCloud and get your publicApiKey
  2. For self-hosted usage: Login to CopilotCloud and get your publicLicenseKey. Self-hosting will not use Copilot Cloud (other than to get your keys).

Error Event Structure

The V2 onError callback fires for any error surfaced by CopilotKitCore — including runtime /info failures, agent connect/run failures, tool argument parse/handler failures, transcription errors, and thread-locked conditions. Each event has the following shape:

ts
import { CopilotKitCoreErrorCode } from "@copilotkit/core";

type CopilotKitErrorEvent = {
  error: Error;
  code: CopilotKitCoreErrorCode;
  context: Record<string, any>;
};
  • error — the underlying Error instance (with message, stack, etc.).
  • code — a stable string enum (CopilotKitCoreErrorCode) you can switch on. Values include runtime_info_fetch_failed, agent_connect_failed, agent_run_failed, agent_run_failed_event, agent_run_error_event, tool_argument_parse_failed, tool_handler_failed, tool_not_found, agent_not_found, agent_thread_locked, transcription_failed, transcription_service_not_configured, transcription_invalid_audio, and subscriber_callback_failed.
  • context — a free-form record carrying whatever extra metadata the error site provides (e.g. agentId, runId, toolName, request URL).
tsx
import { CopilotKitProvider } from "@copilotkit/react-core/v2";
import { CopilotKitCoreErrorCode } from "@copilotkit/core";

<CopilotKitProvider
  publicApiKey="ck_pub_your_key" // or publicLicenseKey for self-hosted
  onError={({ error, code, context }) => {
    switch (code) {
      case CopilotKitCoreErrorCode.AGENT_RUN_FAILED:
      case CopilotKitCoreErrorCode.AGENT_RUN_ERROR_EVENT:
        logToService("Agent run failed", { error, code, context });
        break;
      case CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED:
        logToService("Runtime unreachable", { error, code, context });
        break;
      case CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED:
      case CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED:
        logToService("Tool error", { error, code, context });
        break;
      case CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED:
        // Show "Agent is busy, retry?" UI
        break;
    }
  }}
>
</CopilotKitProvider>;

Common Integration Patterns

Integration with Monitoring (e.g., Sentry)

tsx
import * as Sentry from "@sentry/react";
import { CopilotKitProvider } from "@copilotkit/react-core/v2";

<CopilotKitProvider
  publicApiKey="ck_pub_your_key" // or publicLicenseKey for self-hosted
  onError={({ error, code, context }) => {
    Sentry.captureException(error, {
      tags: {
        copilotkit_code: code,
      },
      extra: {
        context,
      },
    });
  }}
>
</CopilotKitProvider>;

Custom Analytics

tsx
import { CopilotKitProvider } from "@copilotkit/react-core/v2";

<CopilotKitProvider
  publicApiKey="ck_pub_your_key" // or publicLicenseKey for self-hosted
  onError={({ error, code, context }) => {
    analytics.track("copilotkit_event", {
      code,
      error_message: error.message,
      agent_id: context.agentId,
      run_id: context.runId,
    });
  }}
>
</CopilotKitProvider>

Server-side Observability Hooks

In addition to client-side onError, the runtime exposes server-side hooks for LLM request/response/error logging via CopilotObservabilityConfig (see packages/runtime/src/lib/observability.ts). This is the recommended place to wire up backend observability — token counts, latency, full request/response payloads — without depending on the browser.

ts
import { CopilotRuntime } from "@copilotkit/runtime";

const runtime = new CopilotRuntime({
  observability_c: {
    enabled: true,
    progressive: true, // stream tokens/updates as they arrive (vs. buffered)
    hooks: {
      handleRequest: (data) => {
        // data: { threadId?, runId?, model?, messages, actions?, forwardedParameters?, timestamp, provider? }
        logger.info("llm.request", data);
      },
      handleResponse: (data) => {
        // data: { threadId, runId?, model?, output, latency, timestamp, provider?, isProgressiveChunk?, isFinalResponse? }
        logger.info("llm.response", data);
      },
      handleError: (data) => {
        // data: { threadId?, runId?, model?, error, timestamp, provider? }
        logger.error("llm.error", data);
      },
    },
  },
});

The three hooks correspond to the three phases of an LLM call. Custom observability hooks require a valid CopilotKit public API key.

Environment-Specific Setup

Development Environment

tsx
import { CopilotKitProvider } from "@copilotkit/react-core/v2";

<CopilotKitProvider
  runtimeUrl="http://localhost:3000/api/copilotkit"
  publicApiKey={process.env.NEXT_PUBLIC_COPILOTKIT_API_KEY} // For observability
  showDevConsole={true} // Visual errors for fast iteration
  onError={({ error, code, context }) => {
    // Lightweight console logging in dev
    console.log("CopilotKit Event:", { error, code, context });
  }}
>
</CopilotKitProvider>

Production Environment

tsx
import { CopilotKitProvider } from "@copilotkit/react-core/v2";

<CopilotKitProvider
  runtimeUrl="https://your-app.com/api/copilotkit"
  publicApiKey={process.env.NEXT_PUBLIC_COPILOTKIT_API_KEY} // [!code highlight]
  showDevConsole={false} // Hide details from end-users
  onError={({ error, code, context }) => {
    logger.error("CopilotKit Error", {
      error,
      code,
      context,
    });

    // Forward to monitoring
    monitoring.captureError(error, {
      extra: { code, context },
    });
  }}
>
</CopilotKitProvider>

Environment Variables

For Copilot Cloud Users

bash
NEXT_PUBLIC_COPILOTKIT_API_KEY=ck_pub_your_key_here

For Self-Hosted Users

bash
NEXT_PUBLIC_COPILOTKIT_LICENSE_KEY=ck_pub_your_key_here

Troubleshooting

Production Observability Issues

  • No events received in onError:

    • Ensure publicApiKey or publicLicenseKey is set (starts with ck_pub_)
    • Check that your environment variables are loaded
    • Verify errors actually occur (use dev console locally to test)
  • High-volume logging:

    • Keep onError lightweight; batch or throttle before sending to external services
    • Consider filtering events by code to reduce noise

Key Configuration Issues

  • Wrong key type: Make sure you're using publicApiKey for Copilot Cloud or publicLicenseKey for self-hosted
  • Invalid key format: Keys should start with ck_pub_
  • Environment variable not loaded: Check that your environment variables are properly configured for your framework