All error responses include a machine-readable code in UPPER_SNAKE_CASE.AUTH Errors#
| Code | HTTP | When |
|---|
AUTH_INVALID_CREDENTIALS | 401 | Wrong email/username or password |
AUTH_TOKEN_EXPIRED | 401 | Access or refresh token expired |
AUTH_TOKEN_REVOKED | 401 | Refresh token invalidated |
AUTH_EMAIL_TAKEN | 409 | Email already registered |
AUTH_USERNAME_TAKEN | 409 | Username already taken |
USER Errors#
| Code | HTTP | When |
|---|
USER_NOT_FOUND | 404 | Invalid user ID |
USER_USERNAME_TAKEN | 409 | Username conflict on profile update |
USER_BANNED | 403 | Banned user attempts action |
ROOM Errors#
| Code | HTTP | When |
|---|
ROOM_NOT_FOUND | 404 | Invalid roomId or roomCode |
ROOM_FULL | 409 | Join attempt at capacity |
ROOM_ALREADY_JOINED | 409 | Double join |
ROOM_FINISHED | 409 | Action on completed room |
ROOM_INVALID_TRANSITION | 409 | Invalid phase transition |
ROOM_INVALID_CODE | 400 | Malformed or expired invite code |
ROOM_NOT_PARTICIPANT | 403 | User hasn't joined this room |
ROOM_PERMISSION_DENIED | 403 | Role lacks required capability |
ROOM_EDITOR_LOCKED | 409 | Edit/run/submit while locked |
ROOM_EDITOR_NOT_LOCKED | 409 | Unlock when not locked |
ROOM_NOT_AI_MODE | 409 | AI action in peer-mode room |
ROOM_NOT_PEER_MODE | 409 | Peer action in AI-mode room |
ROLE_SWAP Errors#
| Code | HTTP | When |
|---|
ROLE_SWAP_NOT_FOUND | 404 | Invalid swap request ID |
ROLE_SWAP_EXPIRED | 409 | Accept/decline after 30s timeout |
PARTICIPANT Errors#
| Code | HTTP | When |
|---|
PARTICIPANT_NOT_FOUND | 404 | Target user not in room |
PARTICIPANT_CANNOT_CHANGE_ROLE | 409 | Role change during restricted phase |
PROBLEM Errors#
| Code | HTTP | When |
|---|
PROBLEM_NOT_FOUND | 404 | Invalid problem ID |
PROBLEM_DUPLICATE_TITLE | 409 | Title already exists |
EXECUTION Errors#
| Code | HTTP | When |
|---|
EXECUTION_JOB_NOT_FOUND | 404 | Invalid jobId or expired |
EXECUTION_RATE_LIMIT | 429 | Too many runs in window |
EXECUTION_SERVICE_UNAVAILABLE | 503 | Circuit breaker open |
EXECUTION_SERVICE_TIMEOUT | 504 | Circuit breaker timeout |
SUBMISSION Errors#
| Code | HTTP | When |
|---|
SUBMISSION_NOT_FOUND | 404 | Invalid submissionId or expired |
SUBMISSION_RATE_LIMIT | 429 | Too many submissions |
AI Errors#
| Code | HTTP | When |
|---|
AI_HINT_RATE_LIMIT | 429 | Too many hint requests |
AI_MESSAGE_RATE_LIMIT | 429 | Too many AI messages |
AI_SERVICE_UNAVAILABLE | 503 | AI circuit breaker open |
FEEDBACK Errors#
| Code | HTTP | When |
|---|
FEEDBACK_ALREADY_SUBMITTED | 409 | Duplicate feedback |
FEEDBACK_ROOM_NOT_FINISHED | 409 | Room not in wrapup/finished |
SESSION Errors#
| Code | HTTP | When |
|---|
SESSION_NOT_FOUND | 404 | Invalid session ID |
SESSION_NOT_PARTICIPANT | 403 | User not a participant |
SESSION_RECORDING_NOT_FOUND | 404 | No recording exists |
SESSION_WHITEBOARD_NOT_FOUND | 404 | No whiteboard export |
SESSION_AI_MESSAGES_NOT_FOUND | 404 | Not an AI-mode session |
SESSION_REPORT_NOT_READY | 404 | Report not yet generated |
MATCHMAKING Errors#
| Code | HTTP | When |
|---|
MATCH_ALREADY_SEARCHING | 409 | Already in queue |
MATCH_NOT_FOUND | 404 | Invalid match ID |
MATCH_EXPIRED | 409 | Accept/decline after timeout |
RECORDING Errors#
| Code | HTTP | When |
|---|
RECORDING_ALREADY_ACTIVE | 409 | Already recording |
RECORDING_NOT_ACTIVE | 409 | No active recording |
RECORDING_CONSENT_MISSING | 409 | Not all participants consented |
ANALYSIS Errors#
| Code | HTTP | When |
|---|
ANALYSIS_JOB_NOT_FOUND | 404 | Invalid analysis job ID |
COLLAB Errors (Internal)#
These codes are used by the collab-plane's internal HTTP API (service-to-service only, not exposed to frontends).| Code | HTTP | When |
|---|
COLLAB_DOCUMENT_NOT_FOUND | 404 | No Yjs document exists for the given roomId |
COLLAB_DOCUMENT_ALREADY_EXISTS | 409 | Document already initialized for this room |
COLLAB_INVALID_REQUEST | 400 | Missing or malformed request body |
COLLAB_INTERNAL_ERROR | 500 | Unexpected collab-plane error |
SYSTEM Errors#
| Code | HTTP | When |
|---|
VALIDATION_FAILED | 400 | Request body fails validation |
UNAUTHORIZED | 401 | Missing or malformed auth |
FORBIDDEN | 403 | Insufficient global permissions |
RATE_LIMIT_EXCEEDED | 429 | Global rate limit |
INTERNAL_ERROR | 500 | Unexpected server error |
Cross-cutting: UNAUTHORIZED, FORBIDDEN, RATE_LIMIT_EXCEEDED, and INTERNAL_ERROR can occur on any authenticated endpoint and are not listed per-endpoint. Modified at 2026-03-12 05:29:50