Every Roadie endpoint returns failures in one uniform JSON envelope (plan §21.1). The type is one of ten stable categories; code is a stable, machine-readable identifier you can branch on; request_id ties the error to your logs.
Messages never contain provider raw bodies, key material, or internal hostnames. On 429 responses a Retry-After header tells you how long to wait.

Error types

In the TypeScript SDK, each type maps to the RoadieError subclass above — branch with instanceof, or use isRoadieError(err) and read err.type / err.code. Auto-retried reflects the SDK’s status-based retry: it automatically retries 408 / 429 / 5xx responses (honoring Retry-After, capped per attempt) before the error is typed. So every 429 is retried — including quota_error, which shares the status with rate_limit_error — while budget_error (402) and the 4xx client errors are not. A retry that can’t clear in time (an exhausted quota, a still-failing provider) simply surfaces the typed error once retries are exhausted.

Error codes

Codes are grouped by type. Anchor links match the code, so doc_url can deep-link here.

invalid_request_error

invalid_request

  • HTTP status: 400
  • Meaning: The request body failed schema validation (missing/invalid field). param names the field.
  • How to handle: Fix the offending field and resend.

request_validation_failed

  • HTTP status: 400
  • Meaning: A framework-level validation failure on the request.
  • How to handle: Correct the request shape and resend.

model_missing_capability

  • HTTP status: 400
  • Meaning: The requested model exists but cannot satisfy the request (e.g. tools or response_format it does not support).
  • How to handle: Choose a model with the required capability, or drop the unsupported option.

provider_credential_missing

  • HTTP status: 400
  • Meaning: No provider credential (BYOK key) is configured for the resolved provider in this environment.
  • How to handle: Add and validate a provider credential for that provider in the dashboard.

request_canceled

  • HTTP status: 400
  • Meaning: The request was canceled via POST /v1/requests/{id}/cancel (or a client disconnect).
  • How to handle: Expected when you cancel; otherwise ignore.

authentication_error

invalid_key

  • HTTP status: 401
  • Meaning: The bearer credential is not a recognized key or token.
  • How to handle: Check that you are sending a valid secret key or client token.

key_expired

  • HTTP status: 401
  • Meaning: The API key has passed its expiry date.
  • How to handle: Issue a new key (or extend the expiry) in the dashboard.

key_revoked

  • HTTP status: 401
  • Meaning: The API key was revoked (immediately, via the Redis denylist).
  • How to handle: Create a new key; stop using the revoked one.

unauthenticated

  • HTTP status: 401
  • Meaning: No credential was supplied on a route that requires one.
  • How to handle: Send an Authorization: Bearer … header.

permission_error

endpoint_not_allowed

  • HTTP status: 403
  • Meaning: The key’s endpoint allowlist excludes this endpoint.
  • How to handle: Use a key permitted for this endpoint, or widen the key’s restrictions.

model_not_allowed

  • HTTP status: 403
  • Meaning: The key’s model allowlist excludes the requested model.
  • How to handle: Request an allowed model, or widen the key’s allowed_models.

end_user_blocked

  • HTTP status: 403
  • Meaning: The end user attached to the request is blocked.
  • How to handle: Unblock the end user in the dashboard if the block was in error.

insufficient_role

  • HTTP status: 403
  • Meaning: The management actor lacks the role required for this control-plane action.
  • How to handle: Perform the action as a member with a sufficient role.

not_found_error

route_not_found

  • HTTP status: 404
  • Meaning: No route matched the method and path.
  • How to handle: Check the URL and HTTP method against the API reference.

model_not_found

  • HTTP status: 404
  • Meaning: The requested model (or alias) is not in this environment’s catalog.
  • How to handle: Use a model returned by GET /v1/models, or add it to the catalog.

no_eligible_target

  • HTTP status: 404
  • Meaning: An alias resolved, but none of its targets are usable (missing capability or credential).
  • How to handle: Fix the alias targets or add the missing provider credentials.

embeddings_not_supported

  • HTTP status: 404
  • Meaning: The requested model does not expose an embeddings API.
  • How to handle: Use an embeddings-capable model (e.g. openai/text-embedding-3-small).

rate_limit_error

rate_limit_exceeded

  • HTTP status: 429
  • Meaning: A requests-per-window limit was exceeded at some scope (org, project, key, or end user).
  • How to handle: Honor Retry-After and retry; reduce request rate.

concurrency_limit_exceeded

  • HTTP status: 429
  • Meaning: Too many concurrent in-flight requests at some scope.
  • How to handle: Reduce parallelism; retry after in-flight requests drain.

end_user_rpm_exceeded

  • HTTP status: 429
  • Meaning: A specific end user exceeded their per-minute request limit.
  • How to handle: Throttle that end user; honor Retry-After.

quota_error

quota_exceeded

  • HTTP status: 429
  • Meaning: A token or request quota for the current window is exhausted.
  • How to handle: Wait for the window to reset, or raise the quota.

budget_error

budget_exceeded

  • HTTP status: 402
  • Meaning: The project/org spend budget cap was reached (returned as HTTP 402).
  • How to handle: Raise the budget or wait for the budget period to roll over.

provider_error

provider_unavailable

  • HTTP status: 503
  • Meaning: The upstream provider was unreachable or overloaded after gateway retries/fallback.
  • How to handle: Retry with backoff; consider adding a fallback target to your alias.

provider_overloaded

  • HTTP status: 503
  • Meaning: The provider signalled overload (429/503/529) and no fallback succeeded.
  • How to handle: Retry with backoff; add fallback capacity.

timeout

  • HTTP status: 502
  • Meaning: The provider did not respond within the per-try deadline.
  • How to handle: Retry; if persistent, lower max_output_tokens or try another model.

stream_interrupted

  • HTTP status: 502
  • Meaning: The provider stream ended before completion (surfaced as a terminal SSE error frame).
  • How to handle: Retry the request; there is no mid-stream resume.

idempotency_error

idempotency_conflict

  • HTTP status: 409
  • Meaning: The Idempotency-Key was already used with a different request body.
  • How to handle: Use a fresh key for a different request, or resend the identical body.

internal_error

internal_error

  • HTTP status: 500
  • Meaning: An unexpected server error. Details are logged server-side, never echoed to the client.
  • How to handle: Retry with backoff; if it persists, contact support with the request_id.

config_unavailable

  • HTTP status: 500
  • Meaning: The gateway could not load the environment config snapshot.
  • How to handle: Transient; retry with backoff.

Client-side SDK errors

These have no wire envelope — the TypeScript SDK raises them locally. They still extend RoadieError, so isRoadieError catches them too.