skills/copilotkit-debug/references/runtime-debugging.md
CopilotKit v2 runtime (@copilotkit/runtime) runs as a Hono HTTP server. It exposes these endpoints under the configured basePath:
| Endpoint | Method | Purpose |
|---|---|---|
/info | GET | Runtime discovery -- returns version, agent list, capabilities |
/agent/:agentId/run | POST | Start an agent run, returns SSE event stream |
/agent/:agentId/connect | POST | Connect to an existing agent run (Intelligence mode) |
/agent/:agentId/stop | POST | Stop a running agent |
/transcribe | POST | Audio transcription |
/threads | GET/POST/PATCH/DELETE | Thread management (Intelligence mode only) |
"sse")/agent/:id/run request creates a new run and streams AG-UI events as SSE.InMemoryAgentRunner by default."intelligence")CopilotKitIntelligence configuration with apiUrl, wsUrl, apiKey, tenantId.IntelligenceAgentRunner which coordinates via WebSocket.identifyUser callback to resolve authenticated users.Verify the runtime is running: Hit the /info endpoint directly:
curl http://localhost:3001/api/copilotkit/info
Expected response: JSON with version, agents, mode fields.
Check basePath alignment: The basePath in createCopilotEndpoint() must match the runtimeUrl in CopilotKitProvider:
// Server
createCopilotEndpoint({ runtime, basePath: "/api/copilotkit" });
// Client
<CopilotKitProvider runtimeUrl="/api/copilotkit">
Check the Hono app mounting: If using a framework adapter (Next.js, Express), ensure the Hono app is mounted at the right path. The framework's route path combined with basePath must form the full URL.
Proxy/reverse proxy issues: If running behind nginx, Vercel, or similar, ensure the proxy passes the full path and does not strip the prefix.
process.env.PORT or the server's listen configuration.runtimeUrl cannot be resolved.When no cors option is provided to createCopilotEndpoint, the runtime defaults to:
origin: "*" (all origins allowed)credentials: falseWhen using HTTP-only cookies for authentication, you must configure CORS explicitly:
createCopilotEndpoint({
runtime,
basePath: "/api/copilotkit",
cors: {
origin: "https://myapp.com", // Must be explicit, not "*"
credentials: true,
},
});
On the client side, enable credentials:
<CopilotKitProvider
runtimeUrl="https://api.myapp.com/api/copilotkit"
credentials="include"
/>
| Browser Error | Cause | Fix |
|---|---|---|
| "No 'Access-Control-Allow-Origin' header" | Runtime not sending CORS headers | Verify createCopilotEndpoint is handling the request (not a 404 from another handler) |
| "Credential is not supported if origin is '*'" | credentials: true with wildcard origin | Set an explicit origin in the CORS config |
| "Method PUT is not allowed" | Preflight failure | Ensure the runtime's CORS allows the method (default config allows all) |
| CORS error only in production | Different origins in dev vs prod | Update the origin config for the production domain |
Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-HeadersThe /agent/:agentId/run endpoint returns an SSE response:
text/event-streamno-cachekeep-aliveEvents are encoded using @ag-ui/encoder (the EventEncoder class). Each event is a data: line in SSE format.
/info endpoint.beforeRequestMiddleware might be throwing or returning an error response before the agent runs.REASONING_* events (issue #3323).TransformStream writer may block. This is rare with SSE but possible with very high event rates.request.signal aborts and the subscription is cleaned up.RunErrorEvent before the stream closes.Open DevTools > Network tab
Find the POST request to /agent/:id/run
Click the "EventStream" tab (Chrome) or check the Response tab for raw SSE data
Each event should be formatted as:
data: {"type":"RunStarted","runId":"..."}
data: {"type":"TextMessageStart","messageId":"..."}
data: {"type":"TextMessageChunk","delta":"Hello"}
If events stop flowing, the issue is server-side (agent stalled or errored)
The /info endpoint is the first request the client makes. If it fails, no agent interaction is possible.
{
"version": "1.52.0",
"agents": {
"myAgent": {
"name": "myAgent",
"description": "My agent description",
"className": "BuiltInAgent"
}
},
"audioFileTranscriptionEnabled": false,
"mode": "sse",
"a2uiEnabled": false
}
For Intelligence mode, the response also includes:
{
"intelligence": {
"wsUrl": "wss://api.copilotkit.ai/client"
}
}
/info Failuresagents promise rejected (lazy agent loading failed). Check the agents factory function./info failed. See CORS section above.<CopilotKitProvider
runtimeUrl="/api/copilotkit"
headers={{ Authorization: `Bearer ${token}` }}
/>
Headers are sent with every request to the runtime, including /info, /agent/:id/run, etc.
const runtime = new CopilotRuntime({
agents: {
/* ... */
},
beforeRequestMiddleware: async ({ request }) => {
const auth = request.headers.get("Authorization");
// Validate auth, modify request, or throw to reject
return request;
},
});
Headers from the client are available in the runtime middleware but are NOT automatically forwarded to remote agents (A2A). This is a known limitation (issue #3170 and #3425). To forward headers, use middleware to inject them into the agent configuration.