> ## Documentation Index
> Fetch the complete documentation index at: https://docs.labelbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Match a Managed Agents symptom or error code to its cause and fix, for sign-in, keys, organizations, billing, environments, integrations, files, automations, MCP servers and credentials, and sessions.

Start with the stable field, not the message: the response's `code`, a session's `failure.code`, or a setup run's `failure_code`. Messages can change; codes don't. HTTP errors are flat objects with required `code` and `message` fields and optional `details`. Every code is listed in [Errors](/recursion/errors).

## Sign-in and the console

| Symptom | Cause | Fix |
| - | - | - |
| **Sign-in is limited to approved accounts.** | Your account isn't approved for access. | Sign in with an approved account. |
| **Verify your email address with your provider, then sign in again.** | Your identity provider hasn't verified your email address. | Verify it with the provider, then sign in again. |
| **That sign-in link is no longer valid.** | The sign-in attempt can no longer be completed. | Start again from the sign-in page. |

## API keys and authentication

| Code or symptom | Cause | Fix |
| - | - | - |
| `401 unauthorized` | The `Authorization` header is missing or malformed, or the key expired, was revoked, or is inactive. | Send `Authorization: Bearer $RECURSION_API_KEY`. Check the key's status under **API keys**. |
| `401` right after exporting a key | The key was exported in a different shell, or copied with extra characters. | Export it in the shell that runs your code, then check it starts with `rma_`. |
| `400 invalid_request` mentioning `x-organization-id` | A tenant-scoped key sent no `x-organization-id`. | Add `x-organization-id: default` or an organization id, or use an organization-scoped key. See [API keys](/recursion/api-keys). |
| `404 not_found` on every request | `x-organization-id` names an organization you can't reach. | Use `default`, or remove the header for an organization-scoped key. |
| A key stopped working without being revoked | It expired. | Check its status, then create a new key. |
| `503 service_unavailable` before anything ran | The key couldn't be checked right now. | Retry shortly. |

## Organizations and roles

| Code or symptom | Cause | Fix |
| - | - | - |
| `403 forbidden` on create, update, or delete | Your organization role is read-only. | See [Organizations and roles](/recursion/organizations-and-roles). Use an account or key with the developer or admin role. |
| `403 forbidden` when testing an environment's setup | Testing setup needs create and update permission, because it provisions compute. | See [Organizations and roles](/recursion/organizations-and-roles). Use an account or key with the developer or admin role. |
| **Test connection** is missing on an app's row, an MCP server's test says **Testing requires create access.**, or `probeMcpServer` returns `403 forbidden` | Testing a connection or an MCP server needs create permission, which the **Organization user** role doesn't have. | Use an account or key with the developer or admin role. |

## Billing

| Symptom | Cause | Fix |
| - | - | - |
| **Billing** isn't in the sidebar | Your tenant role isn't billing, admin, owner, or primary owner. | Use an account with one of those roles. |
| "The card was declined. Replace it in Stripe, then try again." | The bank declined the charge. | Click **Replace card** below the message, choose another card on Stripe, then come back and buy again. |
| Starting a session or sending a message returns `403 session_start_not_admitted` with `details.reason: "out_of_credit"` | Your tenant has used the credits it bought. New sessions and messages that start a turn are refused. Interrupts still work. | Buy credits, then start the session or send the message again. |
| A session is `idle` with `stop_reason: out_of_credit` | Your tenant ran out of credit while the session was running. It paused before its next model request. Requests already in flight for the tenant complete and are charged, so the balance can end slightly below zero. | Buy credits. It continues on its own within about a minute if it paused in the last 72 hours; otherwise send it a message. A session bound to a Slack thread continues on your next reply there. |
| A session is `idle` with `stop_reason: tenant_suspended` | Your account was suspended while the session was running. The session paused and keeps its data. | Contact support to restore the account, then send a message to continue. |
| Testing setup returns `403 setup_run_not_admitted` with `details.reason: "out_of_credit"` | Your tenant has used its credits, so no setup run was recorded. | Buy credits, then test setup again. |
| Starting work or testing setup returns `403 session_start_not_admitted` or `403 setup_run_not_admitted` with `details.reason: "tenant_suspended"` | Your account is suspended. New work is refused and running sessions pause with `stop_reason: tenant_suspended`; your data is kept. Buying credits does not restore it. | Contact support. |
| Testing setup returns `503 setup_run_admission_unavailable` | The credit check was unavailable, so no setup run was recorded. | Retry with the same `Idempotency-Key`. |

See [Billing](/recursion/billing).

## Environments and setup

| Code or symptom | Cause | Fix |
| - | - | - |
| `422 environment_not_verified` on session start | The setup script has never passed, failed, changed since it passed, or is still being tested. `details.next_action` names the call to make. | Run a setup test, wait for `verified` with `stale: false`, then start again. |
| Setup test fails with `phase: setup` | The script exited with an error or timed out. | Read `failed_line`, `failed_command`, `exit_code`, `hint`, and `stderr_tail`. Fix the script and test again. |
| Setup test fails in another phase | A temporary problem preparing compute. | Retry once before changing the script. |
| `429 setup_run_limit` | Your organization has too many setup runs in flight. | Wait for one in `details.in_flight`, or cancel it. |
| `409 setup_run_in_progress` | A setup test is already running for this environment. | Wait for `details.setup_run_id`, or cancel it. |
| `428 precondition_required` on an environment update | You changed a stored network policy, or turned on privileged access, without `expected_access`. | Read the environment and send its current access settings. |
| Package installs fail in setup or in the session | The environment has no internet access. | Allow the needed destinations, or set **Internet access** to **Enabled**, then test again. |

See [Environments](/recursion/environments).

## Integrations

| Code or symptom | Cause | Fix |
| - | - | - |
| **Add integration** is missing on **Integrations** | Your role can view integrations but not add them. | Ask someone with the organization developer or admin role. |
| An app's row stays **Pending setup** | Nobody finished signing in to the app. | Click **Connect** on the row and finish the sign-in. |
| An app's row shows **Revoked**, or the agent can't reach an app | The app no longer accepts the sign-in. | Reconnect the app on **Integrations**. See [Reconnect an app](/recursion/integrations#reconnect-an-app). |
| The agent can't use a tool in an app | The tool isn't on the app's allow-list, or the app isn't granted to the agent. | Add the tool with **Tools** on the app's row, or grant the app to the agent, then start a new session. |
| Sessions stopped using an app after a catalog update | A tool on the allow-list was reclassified or removed. | Open **Tools** on the app's row, click **Remove**, then **Save tools**. |
| **Reconnect first** when granting an app to an agent | The connection isn't active. | Connect or reconnect it on **Integrations**. |
| `400 invalid_request` on `built_in_integrations` | More than 25 entries, a non-empty `tools`, or a connection that isn't an active built-in integration with at least one tool. | Read `message` and fix the entry. See [Grant apps to an agent](/recursion/integrations#grant-apps-to-an-agent). |
| A session has an `integration_token_mint_failed` warning | Recursion couldn't get a token for the agent's grant from the connected app. The message names the repository or account and the reason, such as a repository that isn't in the GitHub App installation. | Fix what the message names: add the repository to the GitHub App installation and **Reconnect** the connection, or remove it from the grant. If GitHub was unavailable, start a new session. See [GitHub access](/recursion/github). |
| `git` or `gh` is unauthenticated in a session | Expected: GitHub access goes through the agent's GitHub tools, not the sandbox. | Grant GitHub on the agent and ask it to use its GitHub tools. See [GitHub access](/recursion/github). |
| `git` can't reach `github.com` | The environment's network policy blocks GitHub. | Allow the GitHub hosts. See [Allow specific hosts](/recursion/environments#allow-specific-hosts). |

See [Integrations](/recursion/integrations#what-can-go-wrong) for every integration error.

## Files and automations

| Symptom or code | Cause | Fix |
| - | - | - |
| `413 payload_too_large` on public REST `uploadFile` | The file part is over 30 MiB, or its multipart request exceeds the framing allowance. | Upload at most 30 MiB through the API, or use the console for a larger file. See [Files](/recursion/files). |
| `413 file_quota_exceeded` on upload | Your organization's files are at their storage quota. | Set expiries on uploads so they stop counting once they expire. See [Files](/recursion/files). |
| The agent can't find an attached file | It was attached mid-turn. | It's in place on the next tool call and visible from the next turn. |
| A deliverable isn't on the session's **Files** tab | The agent saved it outside the deliverables folder. | Ask for it by name as a deliverable. See [Deliverables and artifacts](/recursion/artifacts). |
| An automation never starts a run | It's paused, its trigger is off, or its event source is paused. | Resume the automation and the source. See [Automations](/recursion/automations). |
| A webhook delivery to a custom source returns `401 unauthorized` | The signature didn't match the source's signing secret. | Sign the exact body bytes with the source's signing secret. See [Send a custom webhook delivery](/recursion/automations#send-a-custom-webhook-delivery). |
| An automation run is `failed` | The session couldn't start. | Read the run's `error`, fix the named field or resource, and run it again. |
| An automation paused itself, or resuming it is refused | Its agent or environment was deleted. | Point the automation at a live agent and environment, then resume it. See [Automations](/recursion/automations). |

## MCP servers and credentials

| Code or symptom | Cause | Fix |
| - | - | - |
| MCP tools are missing from a session | The server couldn't be reached, its handshake failed, it refused the token, or no granted credential matched its URL. | Probe the server and fix the URL, server, token, or vault grant, then start a new session. A running session doesn't pick up new tools. See [MCP servers](/recursion/mcp-servers). |
| An environment-variable secret shows up in the transcript | The agent printed it. Any command in the sandbox can read these secrets. | Rotate the secret. Prefer an MCP credential, which never enters the sandbox. See [Security](/recursion/security). |
| Session fails with `credential_resolution_failed` | A granted credential couldn't be opened, or was deleted. | Check the session's vaults and `credential_refs`. |

## Sessions

| Code or symptom | Cause | Fix |
| - | - | - |
| Session stays `queued` | The agent is at its `max_concurrent_sessions` cap. Child sessions don't count. | Wait for a root session to finish, hard stop one you don't need, or raise the cap. See [Usage and cost](/recursion/usage-and-cost). |
| Session stays `provisioning` | Compute is being prepared. | Read the session, not just its events. After 5 minutes it fails with `sandbox_provision_timeout`; resume it or start again. |
| No events yet, but the session is `running` | The event stream is written separately and can lag the session record. | Trust `status` and `execution_state` from `getSession`. |
| Session `failed` | See `failure.code`, `failure.category`, and `failure.retryable`. | `transient`: send a follow-up to resume. `caller_error`: fix the configuration first. `internal`: report the `session_id`. See [Session failure codes](/recursion/errors#session-failure-codes). |
| `422 sandbox_provider_disabled` | The request names a runtime this deployment doesn't offer for new work. | Use the **Agent runner** runtime (`runs`). |
| Session is `idle` with `end_turn` but the work is incomplete | The agent stopped on its own. `end_turn` doesn't mean correct. | Send a follow-up message with what's missing. |
| `409 idempotency_conflict` | You reused an `Idempotency-Key` with a different request. | Use a new key for a new request. |
| Event stream returns `503 service_unavailable` | The service is at event-stream capacity. | Close streams you no longer need, then retry with backoff. |
| Event stream disconnects | Networks drop long connections. | Reconnect with `Last-Event-ID` or `after_event_id` set to the last event you received. See [Events](/recursion/events). |
| A follow-up after a hard stop starts from a clean workspace | Hard stop tears down the sandbox. | Use **Interrupt** instead when you want to keep the sandbox. |

## Rate limits and server errors

| Code | Cause | Fix |
| - | - | - |
| `429 rate_limit_exceeded` | More than 300 requests in 60 seconds against one of your allowances: all your API keys share one, and console use has its own. | `Retry-After` tells you how long to wait, not whether replay is safe. Retry only when the operation's strategy in **Endpoints** permits it and `details.retryable` is not `false`. |
| `503` | A dependency is temporarily unavailable, or a keyed request could not reserve its idempotency key. | Read `code` and `details.retryable`. Retry only when the operation's strategy in **Endpoints** permits it. `idempotency_unavailable` did not run the request, so resend the same key and request bytes. |
| `504 gateway_timeout` | The request took too long and may have run. | Retry a keyed mutation only with the same key and request bytes. Read the resource before deciding whether to repeat any other write. |
| `500 internal_error` | An unexpected failure. | Retry reads once. For a write, follow the operation's strategy in **Endpoints**. If it persists, report the request id. |

## What to include in a support request

| Field | Why |
| - | - |
| `code` | Selects the recovery path. Do not match `message`. |
| `details.field` | When present, names the request field, query parameter, or header at fault. |
| `details` | When present, holds code-specific state, measured values, limits, and next actions. |
| `details.retryable` | When present, advises whether the failure is transient. It does not override the operation's retry strategy. |
| `details.requestId`, or the `x-request-id` header | Lets support find the request. |
| `session_id` | Identifies the full session tree and its events. |
| `failure.code` and `failure.phase` | Say which stage of a session failed. |
| `setup_run_id` | Identifies a setup test and its log. |
| `recursion-organization-id` response header | Confirms which organization the request ran in. |

Never include an API key or secret value in a support request.

## Next steps

<CardGroup cols={2}>
  <Card title="Errors" href="/recursion/errors">
    Every error and failure code with retry guidance.
  </Card>

  <Card title="Limits" href="/recursion/limits">
    Every limit you can hit.
  </Card>

  <Card title="Event types and states" href="/recursion/reference">
    Decode statuses, stop reasons, and results.
  </Card>

  <Card title="API conventions" href="/recursion/api">
    Retries, idempotency, and paging.
  </Card>
</CardGroup>
