Error Codes

When Bodhi rejects a request, the JSON body carries a stable code (or type) string you can match on. This page is a lookup index for the most-encountered codes. For the shape of each error envelope and how to tell them apart, read Error Format first.

Four envelopes, one underlying error

Bodhi produces a single internal error and serializes it into one of four wire formats based on which compat layer received the request:

Envelope Endpoints Carries code field
Bodhi-native /bodhi/v1/* (UI APIs, MCP CRUD, settings, tokens, app access) Yes — error.code
OpenAI-style /v1/chat/completions, /v1/embeddings, /v1/responses, /v1/models, /api/* Yes — error.code
Anthropic-native /anthropic/v1/messages, /v1/messages, /anthropic/v1/models No — only error.type. 5xx messages are sanitized to "internal server error".
Gemini-native /v1beta/* No — only error.code (HTTP int) and error.status (gRPC string). 5xx messages are sanitized.

The Bodhi-native and OpenAI envelopes preserve the full code string and message. The Anthropic and Gemini envelopes intentionally drop the granular code (their SDKs don't model it) and replace 5xx messages so internal details never leak. If you need the exact reason a 5xx happened, hit a Bodhi-native or OpenAI-style endpoint or check the server logs.

Code naming convention

Codes follow <domain>-<reason>, where the domain is the originating service in snake_case and the reason is the variant name in snake_case. Examples:

  • data_service_error-alias_not_found
  • mcp_error-mcp_not_found
  • auth_context_error-anonymous_not_allowed

Codes are stable across patch releases — match on them in your client. Messages are not stable; do not parse them.

Top error codes by domain

The tables below list the codes you are most likely to encounter as a user or app developer. They are not exhaustive — new codes can ship in any release. If you see one not listed, the code string is still a reliable programmatic identifier.

Auth and tokens

Code HTTP When you see it Likely cause
auth_context_error-anonymous_not_allowed 403 An endpoint requires authentication; you sent no credentials Missing Authorization: Bearer header or session cookie
auth_context_error-missing_token 401 Endpoint requires a token specifically You're authenticated by session but the endpoint is API-only
token_error-invalid_token 401 Token cannot be parsed or hash check fails Truncated, wrong format (bodhiapp_<random>.<client_id>), or revoked
token_error-token_expired 401 Token is no longer valid Refresh failed or token was deactivated
token_scope_error-invalid_token_scope 400 Scope string is not recognized Use scope_token_user or scope_token_power_user
auth_service_error-token_exchange_error 400 OAuth code → token exchange failed Bad redirect URI, expired code, clock skew
role_error-invalid_role 400 Role string is not assignable Use resource_user, resource_power_user, resource_manager, or resource_admin

Models and aliases

Code HTTP When you see it Likely cause
data_service_error-alias_not_found 404 Requested model alias doesn't exist Typo, alias deleted, or you used the file ID instead of alias name
data_service_error-alias_exists 400 Cannot create — alias name already taken Use a different name or edit the existing alias
data_service_error-unsupported 400 Operation not supported for this alias type E.g. trying to edit a system-managed alias
download_service_error-not_found 404 GGUF file not found on HuggingFace Wrong repo or filename
download_service_error-auth 401 HuggingFace rejected the download Set HF_TOKEN for gated repos
api_model_service_error-validation 400 API model config rejected Missing key, invalid base URL, unsupported provider
api_model_service_error-not_found 404 API model alias doesn't exist
api_model_service_error-auth 401 Upstream provider rejected the API key Key is wrong, revoked, or for the wrong account
model_validation_error-* 400 GGUF file failed validation Wrong format, partial download, unsupported architecture

MCPs

Code HTTP When you see it Likely cause
mcp_error-mcp_not_found 404 MCP instance ID doesn't exist Deleted, or you're hitting the wrong tenant
mcp_error-mcp_server_not_found 404 Pre-registered MCP server slug not found Server removed from the catalog by an admin
mcp_error-mcp_disabled 400 Instance is disabled Re-enable in /ui/mcps/
mcp_error-slug_exists 409 Slug already in use Pick a different slug
mcp_error-name_required, -url_required 400 Required field missing on MCP instance Fill in the field
mcp_error-url_invalid, -url_too_long 400 URL failed validation Must be http/https, ≤ 2048 chars
mcp_error-oauth_token_not_found 404 No OAuth token stored for this MCP Re-run the connect flow
mcp_error-oauth_token_expired 400 Stored OAuth token expired and could not refresh Disconnect and re-authorize
mcp_error-oauth_refresh_failed 500 Refresh token round-trip failed Upstream MCP rejected the refresh — re-authorize
mcp_error-oauth_discovery_failed 500 RFC 8414 discovery failed during DCR Server doesn't expose .well-known/oauth-authorization-server; switch to OAuth preregistered
mcp_error-forbidden 403 Caller lacks consent for this MCP Resource not granted in the access request
mcp_server_error-name_required, -url_required, etc. 400 Pre-registered MCP server validation failed Fill in the field

App access

Code HTTP When you see it Likely cause
access_request_error-not_found 404 App access request ID doesn't exist Already approved/rejected or expired
access_request_error-expired 409 Request older than 10 minutes App must submit a new request
access_request_error-already_processed 409 Request already approved/rejected No-op
access_request_error-missing_redirect_uri 400 Required redirect URI missing Include redirect_uri in the create request
access_request_error-version_mismatch 400 Submitted version doesn't match latest Stale draft — refresh and resubmit
access_request_error-kc_registration_failed 500 Upstream OAuth provider could not create the client Retry; if persistent, contact support

Settings

Code HTTP When you see it Likely cause
setting_service_error-invalid_setting_key 400 Tried to PUT/DELETE a non-editable setting Only BODHI_EXEC_VARIANT and BODHI_KEEP_ALIVE_SECS are editable. See Settings precedence
settings_metadata_error-null_value 400 Setting value cannot be null
settings_metadata_error-invalid_value 400 Value not in allowed set / out of range Check allowed options in the UI
settings_metadata_error-invalid_value_type 400 Wrong JSON type for the setting Number expected, got string, etc.

Inference

Code HTTP When you see it Likely cause
inference_error-* 500 llama.cpp process failed or returned non-2xx Variant mismatch (CUDA on a non-GPU box), GGUF too large for VRAM, model crashed mid-stream. Check $BODHI_HOME/logs

Generic

Code HTTP When you see it Likely cause
obj_validation_error-validation_failed 422 Body validation failed Missing required field, wrong type — check error.params for which field
serde_json_error-* 400 Request body is not valid JSON Trailing comma, unquoted key
db_error-* 500 DB query failed Disk full, locked SQLite, PostgreSQL unreachable
reqwest_error-* 500 Outbound HTTP failed Upstream provider down, DNS, certificate
keyring_error-* 500 OS keychain access failed Desktop only — see Troubleshooting

Mapping to envelopes

For Bodhi-native and OpenAI envelopes, the code shown above appears verbatim in error.code. For Anthropic, the closest equivalent is error.type (one of invalid_request_error, authentication_error, permission_error, not_found_error, api_error, overloaded_error). For Gemini, error.status is the gRPC string (INVALID_ARGUMENT, UNAUTHENTICATED, PERMISSION_DENIED, NOT_FOUND, INTERNAL, UNAVAILABLE).

HTTP Bodhi/OpenAI type Anthropic error.type Gemini error.status
400 invalid_request_error invalid_request_error INVALID_ARGUMENT
401 authentication_error authentication_error UNAUTHENTICATED
403 forbidden_error permission_error PERMISSION_DENIED
404 not_found_error not_found_error NOT_FOUND
409 conflict_error invalid_request_error INVALID_ARGUMENT
422 unprocessable_entity_error invalid_request_error INVALID_ARGUMENT
500 internal_server_error api_error (sanitized) INTERNAL (sanitized)
503 service_unavailable overloaded_error (sanitized) UNAVAILABLE (sanitized)

Tips for handling errors programmatically

  • Match on code when available (Bodhi-native and OpenAI envelopes). It is the only stable identifier across releases.
  • For Anthropic and Gemini, branch on the HTTP status and, secondarily, on error.type / error.status.
  • Never parse human messages — they are translated/expanded over time.
  • For 5xx, retry with backoff. Bodhi never includes 5xx detail in the Anthropic and Gemini envelopes; check Bodhi-native logs if you need to know why.
  • Error Format — exact JSON shape per envelope.
  • Roles and scopes — what causes 401 vs 403.
  • Troubleshooting — symptom → cause → fix flow.
  • Swagger UI at /swagger-ui on your running instance — every endpoint's exact error response schemas.