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.
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. |
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. 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. 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. |
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. |
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. |
| 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. |
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. |
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. |
git can’t reach github.com | The environment’s network policy blocks GitHub. | Allow the GitHub hosts. See Allow specific hosts. |
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. |
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. |
| 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. |
| 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. |
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. |
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. |
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. |
| 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. |
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. |
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. |
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. |
| 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. |
Next steps
Errors
Every error and failure code with retry guidance.
Limits
Every limit you can hit.
Event types and states
Decode statuses, stop reasons, and results.
API conventions
Retries, idempotency, and paging.