# 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 the problem once, then read the serve log or the
   [session trace](https://cursor.com/docs/agent-sdk/troubleshooting.md#read-the-session-trace).

## Serve or the playground won't work

| What you see                               | What to do                                                                         |
| ------------------------------------------ | ---------------------------------------------------------------------------------- |
| The playground is blank or lists no agents | Start `agent-sdk serve`, because the playground gets its agents from the server.   |
| Agent-file edits don't appear              | Open the URL that `serve --dev` prints, and press Enter in its terminal to reload. |
| Sessions exist but the list is empty       | The list shows only your own sessions, so use the identity that created them.      |

## A turn fails or misbehaves

| What you see                                                        | What to do                                                                                                                                           |
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reads and greps keep failing with `NGHTTP2_FRAME_SIZE_ERROR`        | Run 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/`. |
| The turn reports a missing API key                                  | Set `CURSOR_API_KEY`, `CURSOR_API_KEY_FILE`, or `CURSOR_SERVICE_ACCOUNT_KEY`, or run `agent-sdk login`.                                              |
| Login works but the model host rejects the key                      | Point `CURSOR_API_BASE_URL` and `CURSOR_BACKEND_URL` at the same API host.                                                                           |
| The first turn reports `[resource_exhausted]`                       | The model is usually out of capacity. If a GitHub event started the turn, check for a GitHub `429` rate-limit response first.                        |
| Replies quote an ancestor `AGENTS.md` or unrelated repository rules | Set `defineAgent({ local: { cwd } })` so the agent doesn't inherit the parent checkout. `/v1/info` shows the current `local.cwd`.                    |
| The model lists IDE meta-tools but never calls named MCP tools      | Set `advertiseTools: true` on the local connection.                                                                                                  |
| Server tools, skills, or seed files are missing                     | Check the discovered project in `/v1/info`, and follow the warning from `validate`.                                                                  |
| `validate` and `run` pass but CI type-checking fails                | Return JSON-shaped tool results, such as object literals or `type` aliases, instead of `interface` types.                                            |

## HTTP returns 401, 403, or 409

| What you see                                 | What to do                                                                                                                           |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `401` outside local development              | Send the bearer token, alias token, or channel credential. Default custom routes accept only direct loopback calls.                  |
| `403` on a stream or follow-up               | Use the identity that created the session.                                                                                           |
| A custom route fails through a tunnel or LAN | Protect the host with `--bearer-token` or channel auth. Use `--allow-anonymous` only behind a proxy that authenticates every caller. |
| `409` on a follow-up                         | Refresh the rotating `continuationToken`. Task sessions don't accept follow-ups.                                                     |
| `409 session_busy` from `call --session`     | Wait for the turn, omit `--session`, or mark a read-only tool `effect: "read"` so it can run alongside the turn.                     |

## A hosted deployment fails or looks stale

| What you see                                                               | What to do                                                                                                                                                                              |
| -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `validate` or `deploy` reports `architecture "v2" requires a named secret` | Replace the literal or getter with a [named secret](https://cursor.com/docs/agent-sdk/deployment.md#add-egress-and-secrets), and set its value with `agent-sdk secret set <slug> NAME`. |
| Local changes don't appear after deploy                                    | `deploy` builds the pushed ref, so commit and push your changes, then deploy again.                                                                                                     |
| The deployment never reaches `running`                                     | Run `agent-sdk deployment get <slug>`, and fix the error it reports.                                                                                                                    |
| A secret or egress change has no effect                                    | Confirm the name with `secret list`, check that the `hosting` block is on the pushed ref, and redeploy.                                                                                 |
| A hosted schedule doesn't fire                                             | Check that the deployment is running and that the schedule is in `bot/schedules/` on the deployed ref.                                                                                  |
| A custom route returns `429`                                               | Wait for the time in `Retry-After`, then send it again.                                                                                                                                 |

## GitHub deliveries fail

| What you see                                  | What to do                                                                                                                 |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `github forward` gets `401` on every delivery | Clear the token variables so the forwarder uses your `gh` login, as in `GITHUB_TOKEN= GH_TOKEN= agent-sdk github forward`. |
| `Hook already exists`                         | Stop the stale forwarder. GitHub allows one per repository.                                                                |
| Direct webhooks are rejected outside `--dev`  | Set the same `GITHUB_WEBHOOK_SECRET` on the signer and the server.                                                         |
| You can't create a forwarder                  | Use `agent-sdk github replay <pr-url>`, which needs only pull access.                                                      |

## Slack doesn't respond

| What you see                                    | What to do                                                                                                                                                                                                    |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Logs say `channel idle ... missing credentials` | Run `agent-sdk slack create --dir <agent>`, then check the prefix with `agent-sdk slack doctor`.                                                                                                              |
| `slack create` waits for workspace approval     | Keep the CLI running and open the **Request approval** link it prints. After an admin approves, select **Retry** in the [Deployed Agents](https://cursor.com/dashboard/deployed-agents) **Add Slack** wizard. |
| The bot ignores ordinary channel posts          | Configure `engagement.channelPosts`, create the app with `--channel-posts`, and invite it to each allowed channel.                                                                                            |

## MCP authorization fails

| What you see                                               | What to do                                                                                                                                                                                                                 |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `must be defineConnection({ url, oauth: true })`           | Add `oauth: true` to the connection, or fix the filename you passed to `mcp oauth`.                                                                                                                                        |
| Local auth works but hosted calls return unauthorized      | Your local OAuth tokens don't reach a deployment. Use a `cursorAccount: true` connection, as described in [Host MCP OAuth](https://cursor.com/docs/agent-sdk/guides/mcp-oauth.md#use-an-oauth-server-from-a-hosted-agent). |
| The model invents `mcp_auth` instead of calling the server | Set `advertiseTools: true` for named local tools, or expose a wrapper through `ctx.host.mcp`.                                                                                                                              |

## Schedules or reminders stall

| What you see                                          | What to do                                                                                                                   |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| A schedule or reminder never fires under `--dev`      | `--dev` doesn't fire them on its own, so trigger one through its `/v1/dev/schedules/<id>` or `/v1/dev/reminders/<id>` route. |
| A reminder is disarmed with `handler_lost_on_restart` | Recreate handler-form reminders after a restart, or use a prompt-form reminder.                                              |
| One schedule fires on several self-hosted processes   | Pass `--no-schedules` to every serving process but one.                                                                      |

## Read the session trace

```bash
agent-sdk session list --prod --slug <slug>
agent-sdk session get <sessionId> --prod --slug <slug> --view events
agent-sdk session get --file <trace-path>
```

Find a hosted session with `session list`, then print its events with
`--view events`. For a local run, pass the trace path from `agent-sdk run`
to `--file`. Pair each `actions.requested` event with its `action.result`
to find the call that failed.


---

## Sitemap

[Overview of all docs pages](/llms.txt)
