# Errors

Every error has a short code, such as `capacity`. Find it below to see what happened and what to do.

- **Python:** errors have `code`, `fix`, `retry` and `docs_url`, a link to the code's row on this page.
- **HTTP:** the body is `{"error": {"code": "...", "message": "..."}}`.
- **Terminal:** `yb errors <code>` explains a code without going online.

## What to do next

Each code has a `retry` value. It tells your program what to do next:

| `retry` | What to do |
|---|---|
| `retry` | Temporary: wait, then repeat the same call with backoff. |
| `fix` | Change what the fix says first; repeating the same call fails the same way. |
| `next_request` | Only this request failed; the session is still open, send the next observation. |
| `new_session` | This session is over; open a new session if you still need one. |
| `none` | A normal ending; nothing to do. |

## Opening a session

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `no_capacity` | No ready copy of this model is running right now. It may be warming up, being replaced, or switched off. Nothing was charged. | Retry with backoff. If the response's `retry` flag is false (in Python, `error.retryable` is False), the model is not offered at all; pick one from `yb models --ready`. | `retry` |
| `capacity` | The model is running, but every session slot on it is taken. Nothing was charged. | Retry shortly, or close one of your own open sessions. | `retry` |
| `session_limit` | This project already has its maximum number of open sessions. | Close a session you no longer use: `yb sessions`, then `yb close <session-id>`. | `fix` |
| `account_session_limit` | The account's open sessions across all its projects reached the ceiling. | Close a session in any of the account's projects. | `fix` |
| `rate_changed` | The model's price changed after your client read it. | Read the new price with `yb models --ready`, then open a new session. | `fix` |
| `insufficient_credit` | Available credit does not cover `max_spend_usd` (or, for a dedicated deployment, its operating window). | Add credit in the dashboard, or lower `max_spend_usd`. | `fix` |
| `spend_limit` | `max_spend_usd` is above the per-session limit. | Use a smaller `max_spend_usd`. Open another session when this one runs out. | `fix` |
| `spend_too_small` | `max_spend_usd` does not cover even one request at this model's rate. | Raise `max_spend_usd`. The rate is listed by `yb models --ready`. | `fix` |
| `model_unavailable` | No enabled model has that name. | Pick a model from `yb models --ready`. | `fix` |
| `idempotency_required` | Opening a session or starting a deployment needs an Idempotency-Key header of 8 to 128 characters. | Send one unique key per logical attempt. The SDK does this for you. | `fix` |
| `idempotency_conflict` | This Idempotency-Key was already used with different parameters. | Use a new key for a different request. Reuse a key only to retry the exact same request. | `fix` |
| `controller_fenced` | The platform's control service stopped making changes to stay safe, because another copy of it may be running. Nothing was changed or charged. | Retry later. An operator must restart the control service. | `retry` |
| `expiring` | The session or deployment is about to reach its end time, so no new session pass is issued. | Open a new session. | `new_session` |
| `session_expired` | The session reached its absolute time limit. | Open a new session. | `new_session` |
| `session_closed` | The session is already closed. A closed session can never be reopened. | Open a new session. | `new_session` |
| `replica_retired` | The model server this session was pinned to was replaced, by a planned renewal or after a failure. Unfinished work was not charged. | Open a new session. It lands on the current model server. | `new_session` |
| `health_stale` | The model server has not reported its health recently. | Retry shortly. A model server that stays silent is replaced automatically. | `retry` |
| `worker_unhealthy` | The model server reports that it is not healthy. | Retry shortly. An unhealthy model server is replaced automatically. | `retry` |
| `not_ready` | The model server or deployment is not accepting sessions yet. | Wait until it is ready, then retry. | `retry` |
| `unavailable` | The platform, an upstream service or the model server is temporarily unavailable. | Retry shortly. Check the operation's state before retrying a mutation and reuse its idempotency key. Do not replay robot observations or actions. | `retry` |
| `draining` | The model server is shutting down, and takes no new sessions. | Open a new session. The platform sends it to the current copy. | `retry` |
| `service_budget` | The platform has no more funded GPU capacity right now. | Retry later. | `retry` |
| `deadline_too_short` | The answer deadline (`max_action_age_ms`) is shorter than this model can ever meet, so every answer would arrive too late. | Raise `max_action_age_ms` to at least the model's minimum, listed by `yb models --ready` under `limits`. | `fix` |
| `slot_share` | This account already holds its share of one model server's places. The rest are kept for other customers. | Close one of your sessions on this model, or wait for one to end. | `fix` |

## During a session

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `expired` | A result would have been too old to use, so it was dropped: the observation waited too long, the model finished after the deadline, or the SDK measured capture-to-receipt age above `max_action_age_ms`. Results the model server drops are not charged. A result the server sent in time, but that reached you late, is. | Send the next observation. If it happens often, raise `max_action_age_ms`, share the model with fewer clients, or run closer to its region. | `next_request` |
| `superseded` | A newer observation arrived before this one started, so this one was dropped. Only the newest waiting observation is kept. | Nothing to do. To get every result, wait for each one before sending the next observation. | `next_request` |
| `invalid_observation` | The observation does not match the model's robot contract: keys, image shape, state size, or prompt. After 20 invalid observations in a row the session closes. | Compare it with the Robot data formats page in the docs. Keep the prompt equal to the session instruction; change it with `reset`. | `fix` |
| `sequence` | Sequence numbers must increase within an episode. | Let the SDK number requests. Numbering restarts after `reset`. | `fix` |
| `identity` | A request or session pass does not match the session: a different session, episode or model, or the model server opened a session other than the one assigned. | Open a new session through the SDK. Never reuse IDs or session passes across sessions. | `new_session` |
| `worker_failed` | The model process failed or timed out, so its sessions closed. Nothing was charged for unfinished work. | Open a new session after a short wait. A replacement copy starts automatically. | `new_session` |
| `spend_exhausted` | The session used up the request allowance its `max_spend_usd` paid for. | Open a new session with a new `max_spend_usd`. | `new_session` |
| `already_connected` | Another client is already connected to this session. A session has exactly one client. | Use one session per robot or process. Open another session for another client. | `fix` |

## Keys, accounts and permissions

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `unauthorized` | No valid key or sign-in: the API key is missing, revoked, expired (keys last 90 days) or mistyped, or the dashboard sign-in ended. | Set YB_API_KEY to a current project key from the dashboard's API keys tab, or sign in again. | `fix` |
| `forbidden` | The key or sign-in is valid, but may not do this. Changing the account needs a signed-in person, not an API key. | Do this step in the dashboard while signed in. | `fix` |
| `scope` | A session pass was used outside its own session. A pass opens exactly one session, on one model server. | Use the SDK's session object for that session, and the project API key for everything else. | `fix` |
| `origin` | A browser request came from a website other than this platform's own address. | Call the API from the dashboard itself or from code running outside a browser. | `fix` |
| `login_failed` | The email or the password is wrong. | Check both, or reset the password from the sign-in page. | `fix` |
| `password_mismatch` | The current password you typed is wrong. | Type the account's current password exactly. | `fix` |
| `account_exists` | An account already uses this email. | Sign in instead, or reset that account's password. | `fix` |
| `account_changed` | The signed-in account no longer matches the account shown when this action was submitted. | Reload the dashboard, confirm the current account and project, then submit the action again. | `fix` |
| `signup_disabled` | This installation is not accepting new accounts. | Ask the operator for access. | `fix` |
| `email_unverified` | The account email is not verified yet, and this action can spend money. | Open the verification link from your email, or request a new one in the dashboard. | `fix` |
| `email_unavailable` | The verification email could not be sent. | Try again in a few minutes. Contact support if it keeps failing. | `retry` |
| `email_unconfigured` | This installation cannot send email, so password reset by email is off. | Ask the operator to reset the password. | `fix` |
| `link_expired` | The email link is invalid, expired or already used. | Request a new link. | `fix` |
| `terms_required` | The account has not accepted the current service terms. | A person signs in to the dashboard and accepts them. An API key cannot accept terms. | `fix` |
| `terms_version_mismatch` | The terms version you accepted is not the one currently published. | Reload the dashboard and accept the version it shows. | `fix` |
| `key_limit` | The project already has the maximum number of API keys. | Revoke a key you no longer use, then create a new one. | `fix` |
| `project_limit` | The account already has the maximum of five projects. | Use one of the existing projects. | `fix` |
| `not_found` | That project, session, deployment or model does not exist, or this key cannot see it. | Check the ID. List what you can see with `yb sessions` or `yb models --ready`. | `fix` |
| `rate_limit` | Too many attempts of one kind in a short time: sign-ins, emails, session opens, deployment starts or checkouts. | Wait, then retry with backoff. Reuse one session for many requests instead of opening one per request. | `retry` |
| `last_project` | The account must retain at least one project. | Rename this project or create another before removing an unused project. | `fix` |
| `project_has_history` | A project with credit, usage or agreements cannot be removed as unused. | Keep its accounting history; contact support if cleanup is needed. | `fix` |
| `recovery_hold` | Public service access is temporarily quarantined for recovery verification. | Retry later or contact support; do not create a new account to bypass recovery. | `retry` |

## Checks inside the Python SDK

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `invalid_argument` | A command argument or local input is invalid. | Check the message and run `yb <command> --help`; correct the input before retrying. | `fix` |
| `input_required` | Noninteractive operation needs input that was not supplied. | Set YB_API_KEY or pipe one project key to `yb setup --json`; keys never belong in command-line arguments. | `fix` |
| `interrupted` | The command was interrupted. An accepted remote operation may still exist. | Inspect the returned session/deployment IDs and usage before retrying; reuse the idempotency key for the same management mutation. | `fix` |
| `diagnostic_findings` | The diagnostic completed and found issues. | Read the findings in the result, make the indicated changes, then run the diagnostic again. | `fix` |
| `local_io_error` | A local file or input/output operation failed. | Check that the input file exists and is readable, then retry the command. | `fix` |
| `unexpected_error` | The command encountered an unexpected implementation or response error. | Inspect any returned operation IDs and contact support with the SDK version before retrying a mutation. | `fix` |
| `unreachable` | The SDK could not reach the platform: network, DNS or TLS failed, or the server is down. | Check YB_URL and your network, then retry with backoff. | `retry` |
| `closed` | A method was called on a session that is already closed. | Open a new session. | `new_session` |
| `reset` | The session was reset elsewhere, so results for the previous episode were discarded. | Continue with the session's current instruction. | `next_request` |
| `reset_timeout` | The server did not confirm a reset in time. | Close the session and open a new one. | `new_session` |
| `revision` | The model server runs a different model version than the one admitted, so the SDK sent nothing. | Open a new session. | `new_session` |
| `schema` | The model server's data format is not the one this client expects, or this SDK version does not know the format. | Upgrade the SDK, or pick the model whose contract your robot code implements. | `fix` |
| `invalid_result` | A result did not belong to the request that was sent (session, episode or sequence). | Open a new session. Report it if it repeats. | `new_session` |
| `connection_lost` | The connection to the model server stopped working: it closed, an observation could not be sent in time, or nothing came back for several requests in a row. The SDK closed the session. | Open a new session. If it keeps happening, check the network between the robot and the service. | `new_session` |
| `fastpath_unavailable` | You asked for UDP (udp="on") and the session cannot use it: the model server does not offer it, the pycryptodomex package is missing, or UDP to the model server is blocked. | Allow outbound UDP to the model server's Fastpath port, install pycryptodomex, or use udp="auto" (the default), which falls back to the WebSocket by itself. | `fix` |
| `invalid_actions` | The model server returned an action chunk with the wrong shape or non-finite values; the SDK refused it. | Open a new session and report the model ID to support. | `new_session` |
| `invalid_credential` | A session pass renewal tried to move the session to another model server or model version; the SDK refused it. | Open a new session. | `new_session` |
| `model_unknown` | No ready model has that name. | List models with `yb models --ready`. | `fix` |
| `request_failed` | The server returned an error without a code. | Read the message and retry once. Report it if it repeats. | `fix` |
| `model_start_timeout` | Model startup exceeded the SDK connection deadline. No inference ran through this connection. | Check the error's cleanup_confirmed field or close its session_id, then open a new session. | `new_session` |
| `model_start_failed` | The connection closed before model startup completed. Model loading is not a customer charge. | Read close_reason in the error context. Retry with a new session after the cause is resolved. | `new_session` |

## Credit and payments

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `checkout_unknown` | The payment provider response was lost or unavailable; the purchase outcome is unknown. | Retry with the SAME Idempotency-Key or inspect payment history. Do not start another purchase just to retry. | `retry` |
| `topup_range` | The top-up amount is outside the allowed range for one purchase. | Choose an amount between the `min_usd` and `max_usd` in the error. | `fix` |
| `payments_unconfigured` | Payments are not connected on this installation. | Ask the operator to add credit. | `fix` |
| `payment_mismatch` | A payment event did not match the recorded checkout, so it was refused and nothing changed. | Nothing for customers to do. The operator investigates. | `fix` |
| `payment_pending` | The internal purchase or original payment needed to reconcile this event is not recorded yet. | The durable inbox retries it. If it persists, the operator reconciles the missing payment record. | `retry` |
| `invalid_signature` | A payment webhook had an invalid signature and was refused. | Nothing for customers to do. The operator checks the webhook secret. | `fix` |
| `credit_forfeiture_required` | Deletion would forfeit unused purchased credit. | Review the balance and explicitly acknowledge forfeiture, or keep the account open. | `fix` |
| `payment_review` | The provider outcome requires manual reconciliation. | Contact support with the payment ID; do not repay to recover the same purchase. | `fix` |
| `review_resolution` | The operator outcome or case note is missing or invalid. | Choose a supported outcome and a short reconciliation reference. | `fix` |
| `refund_unconfirmed` | A full refund has not been confirmed by Stripe. | Reconcile the provider event before recording a completed refund. | `fix` |
| `payment_paid` | A paid purchase cannot be marked uncharged. | Choose the verified payment outcome; preserve its accounting record. | `fix` |
| `payment_unconfirmed` | A purchase has not been confirmed as paid. | Reconcile it with the provider before deciding how its credit is handled. | `fix` |
| `credit_unavailable` | Held credit cannot be released to an inactive account or an unconfirmed purchase. | Review account eligibility and the provider payment first. | `fix` |
| `account_not_closed` | An active or suspended account's credit cannot be forfeited as a deleted account. | Resolve access and release its confirmed credit, or reconcile an exceptional refund. | `fix` |
| `recovery_pending` | A restored account needs review before a payment event can apply. | The operator reconciles account ownership, deletion and balances; the inbox retains the event. | `fix` |

## Dedicated deployments (operators and developers only)

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `source_resource_unverified` | Cleanup is held because the saved resource belongs to an unverified source installation. | The operator must reconcile source-host ownership and provider inventory before confirming cleanup. | `fix` |
| `duration_limit` | The requested deployment duration is longer than the service allows. | Ask for a shorter duration. | `fix` |
| `project_capacity` | The project already has an active deployment. | Stop it before starting another. | `fix` |
| `not_a_deployment_model` | This model is offered as a shared ready model, not as a dedicated deployment. | Open a session on it instead: `client.session(...)` or `yb run`. | `fix` |
| `not_synthetic` | This action needs a ready CPU sandbox deployment. | Use a sandbox deployment for the demo. | `fix` |
| `synthetic_worker` | LIBERO simulator runs need a real model backend, not the CPU sandbox. | Run LIBERO against a GPU model server. | `fix` |
| `worker_unreachable` | The model server's telemetry could not be read. | Retry shortly. | `retry` |
| `busy` | A model server reconnect was requested while sessions are open or the server is still starting. | Close active sessions and wait for start-up to finish, then reconnect. | `fix` |
| `region_unavailable` | No enabled model profile exists in the requested region. | Pick another region, or `auto`. | `fix` |
| `ambiguous_model` | More than one profile matches that model in the region. | Name an exact model profile. | `fix` |
| `probes_unavailable` | Region probes could not be measured from this client. | Name an explicit region instead of `auto`. | `fix` |
| `deployment_unavailable` | The deployment failed or is stopping. | Read its events with `yb logs <deployment>`, then start a new one. | `fix` |
| `readiness_timeout` | The deployment did not become ready in time. It still exists and may still be billed by the hour. | Inspect it with `yb status <deployment>`, or stop it with `yb stop <deployment>`. | `fix` |

## Generic HTTP errors

| Code | What happened | What to do | `retry` |
|---|---|---|---|
| `database_busy` | The platform's database is busy, closing or unable to finish within its wait limit. | Wait for Retry-After, check the operation's current state, and reuse its idempotency key when retrying a mutation. Do not replay robot observations or actions. | `retry` |
| `executor_busy` | The platform's bounded background-processing capacity is temporarily occupied. | Wait for Retry-After and retry with backoff. Reuse the same idempotency key for a management mutation. | `retry` |
| `bad_request` | The request was malformed. | Check the method, path and body against the HTTP API page in the docs. | `fix` |
| `method_not_allowed` | This path does not accept that HTTP method. | Check the HTTP API page in the docs. | `fix` |
| `conflict` | The request conflicts with the current state. | Read the current state, then retry. | `fix` |
| `too_large` | The request body is larger than allowed (1 MiB for management calls). | Send a smaller body. | `fix` |
| `invalid_request` | A field is missing or has the wrong type or range. The error's `fields` list names each one. | Fix the named fields. | `fix` |

## Why a session ended

Every closed session records why it ended, as `close_reason`: in `policy.closure` after `close()`, and in `client.sessions()`. A reason that starts with `worker:`, such as `worker:too_many_expired`, means the model server ended the session before your code closed it. Some reasons share a name with an error code, such as `expired`; this table gives the meaning for a session that ended.

During a session, the SDK raises an `InferenceError` with the model server's reason as its code. When the platform ends a session, for example for `credit_reversed`, the model server reports `client_closed`; the session's `close_reason` has the real reason.

| Reason | What happened | What to do | `retry` |
|---|---|---|---|
| `client_closed` | Your client closed the session. | Nothing to do. | `none` |
| `startup_timeout` | Model startup exceeded the platform deadline. The admission's credit hold was released. | Check model availability before opening another connection. | `new_session` |
| `startup_failed` | The worker stopped before admitting inference. Model loading was not charged. | Wait for the service to recover, then open a new connection. | `new_session` |
| `customer_closed` | The session was closed through the API, `yb close`, or the dashboard. | Nothing to do. | `none` |
| `disconnected` | The client's connection dropped, so the session closed. | Open a new session. Check the network if it repeats. | `new_session` |
| `idle_expired` | No traffic for longer than the idle limit, or no client connected in time. | Open a new session. Close sessions you are not using. | `new_session` |
| `attach_expired` | The session was admitted, but no client connected within the attach window (60 seconds by default). Its slot and credit hold were released. | Connect right after opening, or open a new session. | `new_session` |
| `credential_expired` | The session's pass expired without being renewed. | Open a new session. The SDK renews automatically between requests. | `new_session` |
| `expired` | The session reached its end time. | Open a new session. | `new_session` |
| `deployment_expired` | The model server reached its own end time. | Open a new session. | `new_session` |
| `replica_retired` | The model server was replaced, by a planned renewal or after a failure. Unfinished work was not charged. | Open a new session. | `new_session` |
| `worker_failed` | The model process failed. Unfinished work was not charged. | Open a new session after a short wait. | `new_session` |
| `gateway_stopped` | The model server shut down. | Open a new session. | `new_session` |
| `gateway_restarted` | The model server restarted while the session was open. | Open a new session. | `new_session` |
| `slow_consumer` | The client stopped reading results and 32 unread messages piled up. | Read results as they arrive, then open a new session. | `new_session` |
| `too_many_rejections` | Twenty invalid observations arrived in a row. | Fix the observation format (see the Robot data formats page in the docs), then open a new session. | `new_session` |
| `too_many_expired` | Ten model runs in a row finished after their deadline, so none could be delivered. | Raise `max_action_age_ms`, send fresher observations, or run closer to our region, then open a new session. | `new_session` |
| `credit_reversed` | A refund or dispute took back credit this session's spending cap relied on. Completed requests were settled. | Add credit, then open a new session. | `new_session` |
| `account_deleted` | The account was deleted. | Nothing to do. | `none` |
| `restored` | The platform was restored from a backup; sessions open at that moment were closed without charge. | Open a new session. | `new_session` |
| `test_complete` | A console sandbox test finished. | Nothing to do. | `none` |
| `test_error` | A console sandbox test failed. | Run the test again. | `none` |
