Skip to content

Fix common agent problems ​

Start with three checks:

  1. Run agent-sdk validate --dir ..
  2. Confirm the expected agent and connections in agent-sdk info --dir . --json.
  3. Reproduce once, then inspect the serve log or session trace.

Match the visible symptom below.

Serve or the playground will not work ​

What you seeWhat to do
serve exits before listeningFix the errors from agent-sdk validate --dir ., then start it again.
Playground is blank or says there are no agentsStart agent-sdk serve; built playground assets have no agent data without the server.
Agent-file edits do not appearOpen the URL printed by serve --dev, then press Enter in its TTY to reload after file changes.
Sessions exist but the list is emptyThe list is scoped to the authenticated principal. Use the same identity that created the session; a ?sessionId= deep link does not bypass authorization.
The preferred port is busyUse the next port printed by the CLI, pass --port <number>, or pass --port 0 for any free port.

A model turn fails ​

What you seeWhat to do
File reads and greps fail repeatedly with NGHTTP2_FRAME_SIZE_ERRORRun the agent under Node 22.13 or newer, never Bun.
Semantic search has been removed. Use Grep.Delete search from a custom fs, drop SearchQuery and SearchResult, and remove SemanticSearch or semSearch from tools and bot/tools/. See Migrate off semantic search.
The turn immediately reports a missing API keySet CURSOR_API_KEY, CURSOR_API_KEY_FILE, or CURSOR_SERVICE_ACCOUNT_KEY, or run agent-sdk login.
Login succeeds but the model host rejects the keyPoint login and model traffic at the same API host; check CURSOR_API_BASE_URL and CURSOR_BACKEND_URL.
The first turn reports [resource_exhausted]Treat it as a capacity-shaped error. For a GitHub wake, also check the connected GitHub credential and any GitHub 429 rate limit before assuming the model quota is exhausted.

A turn behaves unexpectedly ​

What you seeWhat to do
Replies quote an ancestor AGENTS.md or unrelated repository rulesInspect local.cwd in /v1/info. Set defineAgent({ local: { cwd } }) or the session workspace explicitly instead of inheriting the parent checkout.
The model lists IDE meta-tools but never calls named MCP toolsSet advertiseTools: true on the local model-visible connection and confirm it under connections in /v1/info.
Server tools, skills, or seed files are absentCheck the discovered project in /v1/info; follow the capability warning from validate.
validate and run pass but CI type-checking failsRun the project type check. Tool results must be JSON-shaped; prefer object literals or type aliases over interface return types.

HTTP returns 401, 403, or 409 ​

What you seeWhat to do
401 outside local developmentSend the configured bearer token, alias token, or channel credential. Default custom routes admit direct loopback only.
403 on a stream or follow-upUse the same authenticated principal that created the session.
A custom channel route fails through a tunnel or LANProtect the shared host with --bearer-token or authored channel auth. Use --allow-anonymous only behind a proxy that authenticates every caller.
409 on a follow-upRefresh the rotating continuationToken and confirm the target is a chat session; task sessions do not accept follow-ups.
409 session_busy from call --sessionWait for the turn, omit --session, or mark a read-only tool with effect: "read" so it can run concurrently.
A custom route fails schema type-checkingAdd the required Zod querySchema for GET, or bodySchema for POST, PUT, and PATCH. See Channels.

A hosted deployment fails or looks stale ​

What you seeWhat to do
validate or deploy reports architecture "v2" requires a named secretA githubChannel credential or a GitLab or Bitbucket webhookSecret is a literal or a getter. Replace it with the quoted { secretName: "NAME" } and set the value with agent-sdk secret set <slug> NAME. See Other hosts.
Local changes do not appear after deploydeploy reads a pushed Git ref, not the working tree. Commit and push the intended ref, then deploy it again.
The deployment never becomes runningRun agent-sdk deployment get <slug>, then act on the reported build or startup error.
A secret or egress change has no effectConfirm the name with secret list, verify the hosting block exists on the pushed ref, and follow the CLI or Deployed Agents prompt to redeploy.
agent-sdk deploy blocked by team egress policyAdd the named hosts to the team egress list, or remove them from hosting.egressDomains, then run agent-sdk deploy again. The bot that is running now keeps its last deployed policy.
Cursor events stopped after redeployEach redeploy replaces the watched repositories. Pass every --cursor-events-repo value again; without the flag, the deployment watches only its GitHub source repository.
session create prints a deliveryId but no sessionIdExpected without --wait: the session is created when the turn starts. Pass --wait, or find it with agent-sdk logs --prod --once --slug <slug>, then follow Verify a hosted turn.
session get <sessionId> --prod shows a running run with no logsRuns lag behind events, and a high-effort turn can take several minutes. Rerun the command; a growing event count means the turn is still working.
A Deployed Agents link to a single session doesn't openCheck the session with agent-sdk session get <sessionId> --prod --slug <slug>.
chat, tool call, skill, session get --view cost, or mcp with --prod exits with a usage errorHosted deployments take --prod only on session list, session get, and logs; session create is always hosted. See Verify a hosted turn.
session create --session <sessionId> reports the session belongs to another channel--session continues only sessions that session create started. Reach Slack, SCM, and custom-route sessions through their own channel.
A custom route returns 202 with no bodyExpected on managed hosting. The handler runs after the response, so deliver results from the channel. See Route responses.
External HTTP rejects the alias tokenUpdate the caller with the current token. If the token is lost or exposed, run agent-sdk deployment rotate-token <slug> and replace it everywhere.
deploy, a hosted session, or an eval run says it is not available with Privacy Mode (Legacy)Switch to Privacy Mode, or ask a team admin if your team enforces this setting. A refused session does not store the message. See Privacy Mode.
deploy says persistent deployments are limited to 1 per teamAnother deployment of the team already sets persistent: true. Remove the setting from one agent, or delete that deployment.
A schedule does not fire on the hosted deploymentMake sure the deployment is running and its release has the schedule. Deploy again with @grok/agent-sdk 0.2.14 or newer.
A request to a custom route gets 429The deployment received more requests than its limit. Wait for the time in Retry-After, then send the request again.

See Deployment for source, credential, and redeployment boundaries.

GitHub deliveries fail ​

What you seeWhat to do
github forward returns 401 on every delivery after creating the hookClear GITHUB_TOKEN and GH_TOKEN for that command so the forwarder uses the gh CLI login: GITHUB_TOKEN= GH_TOKEN= agent-sdk github forward ....
Hook already existsRun one forwarder for the repository and stop the stale process.
Direct webhook deliveries are rejected outside --devConfigure the same GITHUB_WEBHOOK_SECRET on the signer and server. Cursor event pull needs no public webhook or webhook secret.
You cannot create a forwarderUse agent-sdk github replay <pr-url>; it needs pull access instead of repository administration.

The GitHub guide covers event pull, replay, and direct webhooks.

Slack does not respond ​

What you seeWhat to do
Logs say channel idle ... missing credentialsRun agent-sdk slack create --dir <agent>, then check the generated prefix with agent-sdk slack doctor. Use slack init --manual only for an app you own.
slack create is waiting for workspace approvalKeep the CLI running, open the Request approval link it prints, and select Retry in the Deployed Agents Add Slack wizard after an admin approves. See Slack.
The bot ignores ordinary channel postsConfigure engagement.channelPosts, create the app with --channel-posts, and invite it to every allowed channel.

See the Slack guide for app setup and engagement choices.

MCP authorization fails ​

What you seeWhat to do
must be defineConnection({ url, oauth: true })Add oauth: true to the named URL connection or correct the connection filename passed to mcp oauth.
Local auth works but hosted calls return unauthorizedLocally stored OAuth tokens don't reach a deployment. Use a cursorAccount: true connection and connect the server from Deployed Agents. See Host MCP OAuth.
The model invents mcp_auth instead of calling the serverSet advertiseTools: true for named local tools, or expose a host-side wrapper through ctx.host.mcp.

See Host MCP OAuth for the credential lifecycle.

Schedules or reminders stall ​

What you seeWhat to do
A schedule or reminder never fires under --devTrigger it through the matching /v1/dev/schedules/<id> or /v1/dev/reminders/<id> route; development mode does not auto-fire.
A reminder is disarmed with handler_lost_on_restartRecreate handler-form reminders after restart, or use a prompt-form reminder.
The same schedule fires on several self-hosted processesEnable schedules on one serving process per project and pass --no-schedules to the others.

A credential was exposed ​

What you seeWhat to do
A secret value appears in a command, transcript, or shell historyRotate it at the provider, set it again through hidden input or stdin, and test the feature.
An alias token appears outside its secure destinationRun agent-sdk deployment rotate-token <slug>, store the new value outside transcripts, and update every caller.
Someone printed a secret to verify itRotate it. Confirm only the name with agent-sdk secret list <slug>, then redeploy and exercise the feature.

Read the session trace ​

Start with actions.requested and action.result. Count calls by tool name, pair every request with its result, and separate host preparation from tools chosen by the model.

turn.failed with turn interrupted usually means a follow-up or stop ended the turn deliberately. Other failures should have an error event near the tool or model boundary that produced them.

Use the trace path printed by agent-sdk run:

text
agent-sdk session get --file <trace-path>

The playground's Open trace control renders the same trajectory. When the agent runs but makes poor decisions, move from diagnosis to a measured hillclimb.