# Errors

> Every error code, what it means and what to do.

Every error has the same body. Branch on `code`, retry only when `retryable` is true, and look before acting again when `outcome` is `unknown`.

```json
{"error": {"code": "STALE_OBSERVATION", "message": "Input ran since your screenshot. Take a new screenshot first.",
  "request_id": "req_01jb7q0x9v2k8m4n6p3r", "retryable": false, "retry_after": null,
  "outcome": "not_applied", "docs_url": "https://docs.trykubi.com/errors#stale_observation", "details": {"acted_since": 2}}}
```

## 400 Bad request

| Code | Meaning |
|---|---|
| <span id="invalid_argument"></span>`INVALID_ARGUMENT` | A field is missing, malformed or out of range (details.field, details.problem). Fix that field and resend. |
| <span id="coordinate_out_of_range"></span>`COORDINATE_OUT_OF_RANGE` | A point lies outside the coordinate space; it is rejected, never clamped. Use a point inside details.space. |
| <span id="batch_too_long"></span>`BATCH_TOO_LONG` | The batch would run past 28 s, inside the 30 s call limit. Split it into smaller batches. |

## 401 Not signed in

| Code | Meaning |
|---|---|
| <span id="unauthenticated"></span>`UNAUTHENTICATED` | The credential is missing, malformed, unknown, revoked or expired (details.reason). Send a valid key or token. |

## 402 Payment needed

| Code | Meaning |
|---|---|
| <span id="quota_exceeded"></span>`QUOTA_EXCEEDED` | The organization is at its screen cap (details.screen_cap). Delete a screen, or a person asks support for a higher cap. |
| <span id="payment_required"></span>`PAYMENT_REQUIRED` | Payment failed. A person pays at details.pay_url. |
| <span id="credit_exhausted"></span>`CREDIT_EXHAUSTED` | The usage credit that pays for disposable screens is used up (details.balance_usd). A person tops up at details.billing_url, or create a persistent screen. |
| <span id="subscription_required"></span>`SUBSCRIPTION_REQUIRED` | Buying usage credit needs a paid persistent screen first. A person subscribes at details.billing_url. |

## 403 Not allowed

| Code | Meaning |
|---|---|
| <span id="permission_denied"></span>`PERMISSION_DENIED` | The credential lacks details.needed, or is not bound to this screen. Use a credential that has it. |
| <span id="human_only"></span>`HUMAN_ONLY` | Only a signed-in person (dashboard cookie) may call this. Ask a person to do it in the dashboard. |
| <span id="csrf_rejected"></span>`CSRF_REJECTED` | A cookie request changed state without the dashboard's Origin. Send it from the dashboard, or use an API key. |
| <span id="organization_suspended"></span>`ORGANIZATION_SUSPENDED` | The organization is suspended. Stop and tell the user. |
| <span id="account_pending"></span>`ACCOUNT_PENDING` | The account is waiting for approval. Stop and tell the user. |

## 404 Not found

| Code | Meaning |
|---|---|
| <span id="screen_not_found"></span>`SCREEN_NOT_FOUND` | No such screen in your organization (the same answer for another organization's id). List screens for a valid id. |
| <span id="not_found"></span>`NOT_FOUND` | No such operation, exec, key, app, export, template, snapshot or saved screenshot (saved ones go after 30 days). Check the id. |
| <span id="file_not_found"></span>`FILE_NOT_FOUND` | Nothing at that path on the screen. List the folder with listFiles. |

## 409 Conflict

| Code | Meaning |
|---|---|
| <span id="no_capacity"></span>`NO_CAPACITY` | No free machine for a new screen right now; nothing was charged. Retry after retry_after. |
| <span id="stale_observation"></span>`STALE_OBSERVATION` | Input ran (anyone's, a person's in the live view included) or the screen restarted since your screenshot (details.acted_since, details.restarted). Take a new screenshot first. |
| <span id="control_held"></span>`CONTROL_HELD` | A person has control of this screen, so nothing ran. Control ends when they release it, or after 5 minutes with no input from them. Wait retry_after seconds, then take a new screenshot before acting. |
| <span id="screen_not_running"></span>`SCREEN_NOT_RUNNING` | The screen is stopped, starting or stopping. Start it, or wait on its operation. |
| <span id="operation_in_progress"></span>`OPERATION_IN_PROGRESS` | Another power operation runs on this screen. Wait on it, then retry. |
| <span id="idempotency_key_in_use"></span>`IDEMPOTENCY_KEY_IN_USE` | A request with this key is still running. Retry the same request. |
| <span id="unsupported_capability"></span>`UNSUPPORTED_CAPABILITY` | This screen cannot do that (for example a screenless box). Use a screen that can. |

## 413 Too large

| Code | Meaning |
|---|---|
| <span id="payload_too_large"></span>`PAYLOAD_TOO_LARGE` | The body or file is over details.limit_bytes. Send less, or move big files through exec. |

## 415 Wrong content type

| Code | Meaning |
|---|---|
| <span id="unsupported_media_type"></span>`UNSUPPORTED_MEDIA_TYPE` | Wrong Content-Type. Send application/json (application/octet-stream for file uploads). |

## 422 Cannot process

| Code | Meaning |
|---|---|
| <span id="idempotency_key_reused"></span>`IDEMPOTENCY_KEY_REUSED` | This key was used with a different body. Use a new key. |
| <span id="secret_blocked"></span>`SECRET_BLOCKED` | The input contains one of our API keys; nothing was typed or run. Remove the key and resend. |
| <span id="url_not_allowed"></span>`URL_NOT_ALLOWED` | The URL is not public HTTPS: it resolves to a private or reserved address, or redirects. Use a public HTTPS URL. |

## 429 Too many requests

| Code | Meaning |
|---|---|
| <span id="rate_limited"></span>`RATE_LIMITED` | Too many requests. Wait retry_after seconds. |

## 500 Server error

| Code | Meaning |
|---|---|
| <span id="internal"></span>`INTERNAL` | Our bug. Retry with the same Idempotency-Key. |

## 503 Unavailable

| Code | Meaning |
|---|---|
| <span id="screen_unavailable"></span>`SCREEN_UNAVAILABLE` | The screen's host or desktop is not answering. Retry after retry_after. |

## 504 Outcome unknown

| Code | Meaning |
|---|---|
| <span id="outcome_unknown"></span>`OUTCOME_UNKNOWN` | The work may or may not have happened. Look before acting; never resend blindly. |
