Skip to main content

Error reference

On error the envelope's code is the canonical google.rpc.Code integer and data.error carries structured ErrorInfo:

{ "code": 9, "message": "All units of 'Voucher 100K' have been awarded.", "trace_id": "01HX3…",
"data": { "error": {
"status": "FAILED_PRECONDITION", // canonical code name
"reason": "PRIZE_OUT_OF_STOCK", // STABLE machine-readable reason — never renamed
"domain": "muse.game",
"metadata": { "prize_id": "prize_001" }
} } }
  • Branch on reason, not on message (human-readable, may change) or HTTP status.
  • Field validation adds data.error.field_violations[].
  • trace_id is echoed in the X-Trace-Id header and correlates to server logs/metrics.
reasongRPC status (code)HTTPMeaning
VALIDATION_FAILEDINVALID_ARGUMENT (3)400Request/config failed validation (see field_violations).
CHEAT_DETECTEDINVALID_ARGUMENT (3)400Anti-cheat rejected the play.
UNAUTHENTICATEDUNAUTHENTICATED (16)401Missing/invalid token.
PERMISSION_DENIEDPERMISSION_DENIED (7)403Authenticated but lacks the required role.
RESOURCE_NOT_FOUNDNOT_FOUND (5)404Entity does not exist in scope.
SESSION_EXPIREDFAILED_PRECONDITION (9)400Session TTL elapsed before play.
SESSION_CONSUMEDFAILED_PRECONDITION (9)400Single-use session already played.
SESSION_INVALIDFAILED_PRECONDITION (9)400Session unknown / not bound to this player+game.
OUT_OF_TURNSFAILED_PRECONDITION (9)400No remaining plays.
GAME_NOT_ACTIVEFAILED_PRECONDITION (9)400Draft/paused/ended or outside window.
REWARD_INVALID_STATEFAILED_PRECONDITION (9)400Illegal reward lifecycle transition.
TASK_INVALID_STATEFAILED_PRECONDITION (9)400Illegal fulfillment-task transition.
PRIZE_OUT_OF_STOCKABORTED (10)409All units awarded (atomic stock check failed).
ALREADY_EXISTSALREADY_EXISTS (6)409Duplicate create, or a once-only action repeated.
REWARD_ALREADY_CLAIMEDALREADY_EXISTS (6)409Reward already claimed/fulfilled.
CONTACT_CONFLICTALREADY_EXISTS (6)409Verified contact maps to a different identity.
RATE_LIMITEDRESOURCE_EXHAUSTED (8)429Rate limit exceeded; honor Retry-After.
HANDLER_NOT_FOUNDINTERNAL (13)500Config references an unregistered handler/seed/validator.
INTERNALINTERNAL (13)500Unexpected server error.

Reasons are defined in gamekit/gkerr and mapped to gRPC codes in pkg/apierr; the BFF transcodes the gRPC status to HTTP. Unlisted reasons default to INTERNAL (500). This table mirrors docs/ERRORS.md in the repo.