Error Observability Connectors
Manage Error Monitoring, Logging and Alerts.
CopilotKit Premium provides production-grade error observability with the observability solution of your choice via the onError hook on CopilotKit. 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#
import { CopilotKit } from "@copilotkit/react-core/v2";
export default function App() {
return (
<CopilotKit
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}
>
{/* Your app */}
</CopilotKit>
);
}
Key Configuration:
- Use
publicApiKeywhen using Copilot Cloud - Use
publicLicenseKeywhen self-hosting CopilotKit - Both keys provide the same observability features
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.
- For Copilot Cloud hosting: Login to CopilotCloud and get your
publicApiKey - 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:
import { CopilotKitCoreErrorCode } from "@copilotkit/core";
type CopilotKitErrorEvent = {
error: Error;
code: CopilotKitCoreErrorCode;
context: Record<string, any>;
};
error— the underlyingErrorinstance (withmessage,stack, etc.).code— a stable string enum (CopilotKitCoreErrorCode) you can switch on. Values includeruntime_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, andsubscriber_callback_failed.context— a free-form record carrying whatever extra metadata the error site provides (e.g.agentId,runId,toolName, request URL).
import { CopilotKit } from "@copilotkit/react-core/v2";
import { CopilotKitCoreErrorCode } from "@copilotkit/core";
<CopilotKit
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;
}
}}
>
{/* Your app */}
</CopilotKit>;
Common Integration Patterns#
Integration with Monitoring (e.g., Sentry)#
import * as Sentry from "@sentry/react";
import { CopilotKit } from "@copilotkit/react-core/v2";
<CopilotKit
publicApiKey="ck_pub_your_key" // or publicLicenseKey for self-hosted
onError={({ error, code, context }) => {
Sentry.captureException(error, {
tags: {
copilotkit_code: code,
},
extra: {
context,
},
});
}}
>
{/* Your app */}
</CopilotKit>;
Custom Analytics#
import { CopilotKit } from "@copilotkit/react-core/v2";
<CopilotKit
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,
});
}}
>
{/* Your app */}
</CopilotKit>
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.
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#
import { CopilotKit } from "@copilotkit/react-core/v2";
<CopilotKit
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 });
}}
>
{/* Your app */}
</CopilotKit>
Production Environment#
import { CopilotKit } from "@copilotkit/react-core/v2";
<CopilotKit
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 },
});
}}
>
{/* Your app */}
</CopilotKit>
Environment Variables#
For Copilot Cloud Users#
NEXT_PUBLIC_COPILOTKIT_API_KEY=ck_pub_your_key_here
For Self-Hosted Users#
NEXT_PUBLIC_COPILOTKIT_LICENSE_KEY=ck_pub_your_key_here
Troubleshooting#
Production Observability Issues#
-
No events received in
onError:- Ensure
publicApiKeyorpublicLicenseKeyis set (starts withck_pub_) - Check that your environment variables are loaded
- Verify errors actually occur (use dev console locally to test)
- Ensure
-
High-volume logging:
- Keep
onErrorlightweight; batch or throttle before sending to external services - Consider filtering events by
codeto reduce noise
- Keep
Key Configuration Issues#
- Wrong key type: Make sure you're using
publicApiKeyfor Copilot Cloud orpublicLicenseKeyfor 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
