# HTTP Error Codes This document is the source of truth for backend RFC7807 `code` values consumed by frontend. ## Auth | code | status | meaning | frontend handling | |---|---:|---|---| | `AUTH_SERVICE_UNAVAILABLE` | 503 | Auth upstream unavailable | Show retry message and allow retry | | `AUTH_TOO_MANY_REQUESTS` | 429 | OTP request throttled | Show wait message | | `AUTH_VERIFICATION_CODE_INVALID` | 401 | Invalid OTP code | Prompt user to re-enter code | | `AUTH_REFRESH_TOKEN_INVALID` | 401 | Invalid/expired refresh token | Clear local session and return login | | `AUTH_REFRESH_TOKEN_MISSING` | 401 | Refresh token missing on logout | Treat as local logout and clear session | | `AUTH_USER_NOT_FOUND` | 404 | User not found | Show not-found message where applicable | | `AUTH_UNAUTHORIZED` | 401 | Missing or invalid auth credentials | Force logout and redirect to login | ## Agent Points | code | status | meaning | frontend handling | |---|---:|---|---| | `POINTS_INSUFFICIENT_BALANCE` | 402 | Not enough points to start this run | Show recharge/insufficient-points prompt | | `POINTS_INVALID_CURSOR` | 422 | Points ledger pagination cursor is not a valid ISO 8601 datetime | Show invalid-request message and reload from first page | ## Agent Session | code | status | meaning | frontend handling | |---|---:|---|---| | `AGENT_SESSION_RUN_LIMIT_EXCEEDED` | 409 | Session already reached max message count (2 user messages per session: initial divination + 1 follow-up) | Show run-limit message and require starting a new session | | `AGENT_RUNTIME_MODE_INVALID` | 422 | Missing or invalid `forwardedProps.runtime_mode` in run request | Show invalid-request message and retry from current page | | `AGENT_DIVINATION_PAYLOAD_REQUIRED` | 422 | Missing required `forwardedProps.divinationPayload` in run request | Prompt user to restart casting flow and resubmit | | `AGENT_SESSION_ID_INVALID` | 422 | Invalid session/thread id format | Show invalid-session message and force refresh history | | `AGENT_SESSION_NOT_FOUND` | 404 | Session does not exist (including follow-up on non-existing thread) | Show session-not-found message and refresh history | | `AGENT_USER_ID_INVALID` | 422 | Invalid user id in request context | Show invalid-request message | | `AGENT_AUDIO_UNSUPPORTED_FORMAT` | 400 | Audio format is not accepted by transcribe endpoint | Show format hint and ask user to retry with wav audio | | `AGENT_AUDIO_TOO_LARGE` | 400 | Audio file exceeds transcribe size limit | Show size-limit message and ask user to shorten audio | | `AGENT_AUDIO_EMPTY` | 400 | Uploaded audio payload is empty | Show retry hint and keep input unchanged | | `AGENT_ASR_UNAVAILABLE` | 502 | Upstream ASR service unavailable | Show retry message and allow fallback to text input | | `AGENT_PAYLOAD_INVALID` | 422 | Parsed run input payload is invalid | Show invalid-request message and retry from current page | | `AGENT_RUN_INPUT_INVALID` | 422 | Run request body fails validation | Show invalid-request message and retry | | `AGENT_RUN_MESSAGES_INVALID` | 422 | Run request messages contract violation | Show invalid-request message and retry | | `AGENT_INVALID_RUN_ID` | 422 | Invalid or missing `runId` query parameter | Show invalid-request message and retry | | `AGENT_INVALID_LAST_EVENT_ID` | 422 | Invalid `Last-Event-ID` header format | Retry without the header | | `AGENT_SSE_CONNECTION_LIMIT` | 429 | Too many concurrent SSE connections per user | Show connection-limit message and reduce concurrent streams | | `AGENT_FORBIDDEN` | 403 | User does not own the session resource | Force refresh and show unauthorized message | | `AGENT_ATTACHMENT_EMPTY` | 422 | Uploaded attachment payload is empty | Show retry hint and keep input unchanged | | `AGENT_ATTACHMENT_TOO_LARGE` | 413 | Attachment file exceeds size limit | Show size-limit message and ask user to use smaller file | | `AGENT_ATTACHMENTS_TOO_MANY` | 422 | Too many attachments in single message | Show attachment limit message | | `AGENT_ATTACHMENT_UNSUPPORTED_TYPE` | 422 | Attachment mime type is not supported | Show unsupported type message | | `AGENT_ATTACHMENT_UPLOAD_FAILED` | 502 | Backend failed to upload attachment to storage | Show retry toast | | `AGENT_ATTACHMENT_STORAGE_UNAVAILABLE` | 503 | Attachment storage service unavailable | Show retry message | | `AGENT_ATTACHMENT_BUCKET_INVALID` | 422 | Attachment bucket name is invalid | Show generic error and force refresh | | `AGENT_ATTACHMENT_PATH_SCOPE_INVALID` | 422 | Attachment path does not belong to user scope | Show generic security error and force refresh | | `AGENT_SIGNED_URL_GENERATION_FAILED` | 502 | Backend failed to generate attachment signed URL | Show retry toast | | `AGENT_SIGNED_IMAGE_URL_INVALID` | 422 | Signed image URL is invalid or expired | Show error and retry image load | ## Agent Internal (Binary URL Validation) | code | status | meaning | frontend handling | |---|---:|---|---| | `INVALID_BINARY_URL_HOST` | 422 | Binary URL host is not allowed | Show error and retry | | `INVALID_BINARY_URL_BUCKET` | 422 | Binary URL bucket name is invalid | Show error and retry | | `INVALID_BINARY_URL_PATH_SCOPE` | 422 | Binary URL path does not belong to allowed scope | Show error and retry | ## Profile | code | status | meaning | frontend handling | |---|---:|---|---| | `PROFILE_PAYLOAD_INVALID` | 422 | Profile update payload invalid (length/type/empty constraints) | Highlight invalid fields and block submit | | `PROFILE_NOT_FOUND` | 404 | User profile row missing | Show retry and optionally trigger profile bootstrap | | `PROFILE_DELETE_FAILED` | 502 | Backend failed to complete account hard deletion | Show delete-failed message and allow retry | ## Avatar | code | status | meaning | frontend handling | |---|---:|---|---| | `AVATAR_FILE_INVALID` | 422 | Avatar mime type or size is invalid | Show file validation hint and ask user to pick another image | | `AVATAR_PATH_SCOPE_INVALID` | 422 | Avatar path does not belong to current user scope | Show generic security error and force refresh | | `AVATAR_SIGNED_URL_FAILED` | 502 | Backend failed to generate avatar signed upload URL | Show retry toast and keep previous avatar | | `AVATAR_UPLOAD_FAILED` | 502 | Backend failed to upload avatar bytes to storage | Show retry toast and keep previous avatar | ## Notification | code | status | meaning | frontend handling | |---|---:|---|---| | `NOTIFICATION_NOT_FOUND` | 404 | Notification not found or not owned by current user | Show not-found message and refresh list | | `NOTIFICATION_INVALID_CURSOR` | 422 | Notification pagination cursor is not a valid ISO 8601 datetime | Show invalid-request message and reload from first page | ## Invite | code | status | meaning | frontend handling | |---|---:|---|---| | `INVITE_CODE_NOT_FOUND` | 404 | Invite code not found for current user | Show not-found message and trigger invite code bootstrap | ## Feedback | code | status | meaning | frontend handling | |---|---:|---|---| | `FEEDBACK_CONTENT_EMPTY` | 400 | Feedback content is empty | Prompt user to enter content | | `FEEDBACK_CONTENT_TOO_LONG` | 400 | Feedback content exceeds 500 characters | Show character limit hint | | `FEEDBACK_TOO_MANY_IMAGES` | 400 | More than 3 images uploaded | Show image count limit hint | | `FEEDBACK_IMAGE_TOO_LARGE` | 400 | Image file exceeds 5 MB | Show image size limit hint | | `FEEDBACK_INVALID_IMAGE_TYPE` | 400 | Image type not supported (only jpg/png) | Show supported format hint | | `FEEDBACK_SUBMIT_FAILED` | 500 | Feedback submission failed | Show retry prompt | ## Payment (Apple IAP) | code | status | meaning | frontend handling | |---|---:|---|---| | `PAYMENT_PRODUCT_NOT_FOUND` | 404 | `productCode` does not exist or is not enabled | Refresh packages and show product-unavailable message | | `PAYMENT_PRODUCT_MISMATCH` | 422 | Client product ID does not match backend/Apple verification result | Block grant and prompt retry | | `PAYMENT_TRANSACTION_INVALID` | 422 | Apple signed transaction invalid, signature verification failed, or payload malformed | Show purchase-verification-failed message | | `PAYMENT_TRANSACTION_REVOKED` | 409 | Transaction has been revoked or refunded, grant not allowed | Show purchase-unavailable message | | `PAYMENT_TRANSACTION_CONFLICT` | 409 | Transaction already processed by another user or in conflicting state | Prompt to contact support or refresh balance | | `PAYMENT_STARTER_PACK_INELIGIBLE` | 409 | Current email identity has already purchased starter pack | Refresh packages and hide starter pack | | `PAYMENT_APPLE_UNAVAILABLE` | 503 | (RESERVED) Apple Server API or certificate fetch unavailable | Show retry-later message; do NOT complete/finish transaction | | `PAYMENT_GRANT_FAILED` | 500 | (RESERVED) Verification succeeded but grant transaction failed | Show retry-later message; retain transaction for compensation | | `PAYMENT_REFUND_INSUFFICIENT_BALANCE` | 409 | (RESERVED) User has insufficient balance for refund clawback | Log for manual review; do not auto-clawback | ## Global | code | status | meaning | frontend handling | |---|---:|---|---| | `REQUEST_VALIDATION_ERROR` | 422 | Request validation failed | Show invalid-request message | | `INTERNAL_ERROR` | 500 | Unexpected internal server error | Show generic error and allow retry | ## Tool (Internal Agent Runtime) | code | status | meaning | frontend handling | |---|---:|---|---| | `MISSING_RUNTIME_ARGS` | 500 | Tool call missing required runtime arguments | Show error and retry | | `TOOL_REJECTED` | 403 | Tool execution was rejected | Show tool rejection message | | `TOOL_PENDING_APPROVAL` | 202 | Tool execution awaiting approval | Show pending approval state |