Version: Current
Historical release snapshot. These docs are frozen. Read current docs.
What to do with an error
Every error body carries acumen_code, acumen_class, retryable,
retry_after_ms and request_id. The code is the same string on every door, so
a client can branch on it without parsing prose. Read the class first, then
retryable and retry_after_ms, then the code. A retry without reading those
three fields is a guess.
The generated error code index is the full list with the source line of each code. This page is the action for each code, grouped by the class it belongs to.
| Class | Status | Retryable | Retry-After | What to do |
|---|---|---|---|---|
auth |
401, 403 | no | none | Fix the credential. A retry with the same credential fails the same way. |
rate_limit |
429 | yes | at least 1s | Wait for retry_after_ms, then retry. If it repeats, lower the request rate or raise the key’s limit. |
budget |
402 | no | window reset, when the code has one | The window is spent. Wait for the reset, raise the cap, or use a key with budget left. |
model_unavailable |
404, 403, 503, 410, 400 | some | only for a stale catalog | Check the model id, the key’s model allowlist and the seat health. |
contract |
400, 413, 415, 412 | no | none | The body is the problem. Fix the field named in errors[]. |
idempotency |
409, 422 | only in flight | 1s for in flight | Wait when the request is in flight. Do not reuse a key with a different body. |
upstream |
502, 503, 504 | yes | from the vendor, clamped to 6h | The seat failed. Retry with backoff; if it repeats, check that seat’s credential. |
gateway |
500, 501, 503, 400 | some | 1s on the retryable 503s | Retry a 503 with retry_after_ms. Do not retry a 500, a 501 or a 400. |
not_found |
404 | no | none | The path or the object does not exist. Check the route and the id. |
Nothing in this class is retryable: the credential or the session has to change.
auth_missing: send anAuthorization: Bearerheader with a virtual key.auth_invalid,auth_revoked,auth_expired: mint a key, or rotate the one you hold.auth_scope: the key does not carry the scope for this route. Request one with the scope, or use a key that has it.auth_process_token: the process token is for the control plane, not the model doors.auth_session: the browser session is not valid. Sign in again.creds_seat_side_only: vendor credentials are accepted only by the seat, not by a client call. Call the gateway with a virtual key and let the seat hold the vendor credential.
rate_limit
Section titled “rate_limit”Every code in this class is retryable and carries retry_after_ms.
rate_rpm: requests per minute.rate_tpm: tokens per minute.rate_concurrency: concurrent requests against one key.rate_tenant: the whole tenant, shared by its keys.rate_ip: the source address, used when no key authenticated the request.limit_exceeded: the aggregate limit across all dimensions. Wait forretry_after_msand retry.
Wait for retry_after_ms and retry. A burst that keeps hitting the same code is
a pacing problem: spread the work, or raise that dimension’s limit on the key.
budget
Section titled “budget”Nothing in this class is retryable until the window resets or an operator changes the cap.
budget_key_daily,budget_key_weekly,budget_key_monthly: the key’s own cap. The window reset is the retry time. Raise the cap or wait.budget_project,budget_tenant,budget_seat,budget_pool_exhausted: the shared budget is spent, not the key’s. An operator raises the pool; a client retry does not.budget_reservation_failed: the reservation could not be held, so the request was refused before it cost anything. Retry once after the next billing tick; a repeat is an operator issue.budget_unavailable: the budget service is not reachable. Retry with backoff; if it repeats, the operator must restore the service.wallet_floor_refused: the balance is at or below the configured floor. Top up, or lower the floor deliberately.wallet_balance_stale: the balance cache is stale. Retry once; if it repeats, the operator must check the wallet service.
model_unavailable
Section titled “model_unavailable”model_unknown,model_not_found: callGET /v1/modelsand use an id from the list.model_not_allowed: the key’s model allowlist excludes it. Change the key or the model.model_no_eligible_seat: no seat can serve it now. Retryable, with no Retry-After. Check the capacity page before you retry in a loop.model_catalog_stale: the catalog has not refreshed. Retry after the interval inretry_after_ms.model_deprecated: gone by design. Move to the model’s replacement.model_capability_unsupported: the model does not support this door or capability. Choose a model that does.
contract
Section titled “contract”Nothing in this class is retryable: the same body fails the same way.
contract_unsupported: the request declares a contract version this door does not serve. Checkcontractin the response and use a supported version.schema_invalid,payload_too_large,unsupported_media_type,precondition_failed: fix the request. Theerrors[]array names the field and a JSON Pointer.
idempotency
Section titled “idempotency”idempotency_in_flight: wait one second and retry the identical request.idempotency_conflict: the same key was used with a different body. Use a new key.idempotency_stream_completed: the stream already finished; do not replay it.idempotency_replay_unavailable: the replay window closed. Resend the request with a new key.
upstream
Section titled “upstream”The seat failed, not the client. Every code here is retryable, with a Retry-After taken from the vendor and clamped to six hours.
upstream_error,upstream_timeout,upstream_rate_limited: retry with backoff. A repeat on the same seat is that seat’s fault; exclude it or fix its credential.upstream_empty,upstream_protocol: the seat answered, but not with a usable body. Retry once, then report the seat and therequest_id.upstream_auth: the vendor rejected the seat credential. Retryable because a retry can route to another seat; on a pinned seatretryableis false, because the same seat with the same credential cannot succeed. The seat needs an operator.
gateway
Section titled “gateway”store_unavailable,overloaded,draining: retry afterretry_after_ms.store_schema_mismatch: retry afterretry_after_msonce. A repeat means the running binary and the store disagree, which is an operator fix, not a client one.internal,not_implemented: do not retry. Report therequest_id.secrets_not_accepted: a secret value was sent where a reference belongs. Send the credential id, not the credential.seat_reauth_required,seat_credential_missing,seat_credential_unavailable,cli_oauth_disabled,base_url_rejected,wallet_balance_stale: the seat or the wallet needs an operator. Retrying does not change it.budget_unavailable: the budget service is not reachable. Retry with backoff; if it repeats, the operator must restore the service.byok_unavailable: the BYOK credential is not configured or not reachable. An operator must configure the credential; a client retry does not change it.
not_found
Section titled “not_found”resource_not_found: check the id. The route exists, the object does not.route_not_found: check the path and the door. Nothing is served there.
What to send with a report
Section titled “What to send with a report”Include the request_id, the acumen_code, the door path and the time. Do not
include a key value. A key id is enough to find the request; the key itself is a
secret.