Skip to content

Latest commit

 

History

History
103 lines (99 loc) · 25 KB

File metadata and controls

103 lines (99 loc) · 25 KB

playtesthub — gRPC error-code reference

Byte-exact error codes and messages surfaced by MVP RPCs. This document is the byte-exact reference implementers build against. If any row here diverges from PRD prose, the PRD prose is authoritative and the row in this table is a bug.

Consolidated from prose in PRD §4.1, §4.3, §4.6, §5.1, §5.4, §5.6 for implementer convenience.

RPC Condition gRPC code Message (byte-exact)
any admin RPC caller's IAM permission claim lacks ADMIN:NAMESPACE:{namespace}:EXTEND:APPUI at the required action bit (per-RPC CREATE / READ / UPDATE / DELETE — declared via proto options) — PRD §6 AuthZ PermissionDenied (implementation-defined; message SHOULD reference the missing EXTEND:APPUI permission and required action, but MUST NOT echo the caller's actual permission claim)
any RPC request lacks a Bearer token, or the token fails AGS IAM JWKS validation — PRD §6 Security Unauthenticated (implementation-defined; standard Unauthenticated)
CreatePlaytest request specifies distributionModel=AGS_CAMPAIGN in M1 — PRD §4.6 / §10 M1 Unimplemented (implementation-defined; message SHOULD reference that AGS_CAMPAIGN lands in M2)
ApproveApplicant fenced finalize affects 0 rows (reservation reclaimed and re-reserved mid-approve) — §4.1 6b Aborted reservation expired, please retry
ApproveApplicant two admins click Approve on the same PENDING applicant simultaneously — §5.4 FailedPrecondition applicant already approved
RejectApplicant applicant read as PENDING but a concurrent Approve commits before RejectCAS runs (CAS-race) — §5.4 FailedPrecondition applicant was approved before reject could complete
ApproveApplicant pool empty at reserve time, STEAM_KEYS playtest — §5.4 ResourceExhausted No codes remaining in pool. Upload more codes to continue approving.
ApproveApplicant pool empty at reserve time, AGS_CAMPAIGN playtest — §5.4 ResourceExhausted No codes remaining in pool. Generate more codes to continue approving.
ApproveApplicant attempt to approve a REJECTED applicant — §5.4 FailedPrecondition applicant is rejected and cannot be re-approved
ApproveApplicant / RejectApplicant playtest status = CLOSED — §5.4 FailedPrecondition playtest is closed; approve/reject is no longer allowed
ApproveApplicant / RejectApplicant playtest status = DRAFT (defensive; signup is impossible in DRAFT per §5.1 visibility, so unreachable in practice) — §5.4 / Table A FailedPrecondition playtest is in draft; approve/reject requires OPEN status
CreatePlaytest namespace has reached the 100-playtest soft cap — PRD §6 Pagination ResourceExhausted (implementation-defined; message SHOULD reference the 100-playtest cap)
CreatePlaytest slug collision within namespace — §5.1 AlreadyExists (implementation-defined; message SHOULD reference the offending slug)
CreatePlaytest / EditPlaytest ndaRequired=true with empty ndaText — §5.3 InvalidArgument (implementation-defined; message SHOULD reference that nda_text is required when nda_required is true)
CreatePlaytest / EditPlaytest both startsAt and endsAt set with endsAt <= startsAt — §5.1 "Window-driven auto-transition" InvalidArgument ends_at must be after starts_at
CreatePlaytest (STEAM_KEYS) initialCodeQuantity set — STEAM_KEYS sources codes from admin CSV upload; only AGS_CAMPAIGN consumes the field (§4.6 / §5.1) InvalidArgument (implementation-defined; message SHOULD reference that initial_code_quantity is not valid for STEAM_KEYS)
CreatePlaytest / EditPlaytest auto_approve=true and auto_approve_limit NULL or outside 1–100,000 — §5.1 / §5.4 "Auto-approve" InvalidArgument auto_approve_limit must be between 1 and 100000 when auto_approve is true
EditPlaytest attempt to edit any immutable field (incl. distributionModel, slug, namespace, status, initialCodeQuantity, ags* IDs, timestamps) — §5.1 InvalidArgument (implementation-defined; message MUST reference the offending field name)
TransitionPlaytestStatus invalid transition (e.g. DRAFT → CLOSED, or any backward transition) — §5.1 FailedPrecondition (implementation-defined; message SHOULD reference the invalid transition)
AGS-backed RPCs (CreatePlaytest AGS_CAMPAIGN, TopUpCodes, SyncFromAGS) upstream AGS returned HTTP 429 — §4.6 / ags-failure-modes.md ResourceExhausted (implementation-defined; message SHOULD reference upstream AGS rate limit)
AGS-backed RPCs (CreatePlaytest AGS_CAMPAIGN, TopUpCodes, SyncFromAGS) upstream AGS returned HTTP 5xx / timeout after 3 retries exhausted — §4.6 / ags-failure-modes.md Unavailable (implementation-defined; message SHOULD reference upstream AGS unavailability and retry exhaustion)
UploadCodes non-UTF-8 CSV file — §4.3 InvalidArgument (implementation-defined; message SHOULD reference UTF-8 requirement)
UploadCodes bounds / charset / duplicate violation (whole-file reject) — §4.3 InvalidArgument (implementation-defined; response body lists offending line numbers / values)
CreatePlaytest (AGS_CAMPAIGN) initialCodeQuantity outside 1–50,000 — §4.6 / §5.1 InvalidArgument (implementation-defined; message SHOULD reference the 1–50,000 bound)
GetPlaytest (unauth) slug targets a DRAFT, CLOSED, or soft-deleted playtest — §5.1 NotFound (empty / standard NotFound; indistinguishable from non-existent slug)
GetPlaytestForPlayer DRAFT or soft-deleted playtest, or CLOSED playtest for a non-approved caller — §5.1 NotFound (empty / standard NotFound)
GetGrantedCode any soft-deleted playtest, regardless of applicant state — §5.1 NotFound (empty / standard NotFound)
SubmitSurveyResponse second submit by the same (playtestId, userId) — §4.7 / §5.6 AlreadyExists (empty body)
CreateSurvey second Create for the same playtest (a survey already exists) — §4.7 / schema.md §"Survey entity spec" AlreadyExists (implementation-defined; message SHOULD reference using EditSurvey to update an existing survey)
CreateSurvey / EditSurvey empty questions, more than 50 entries, or any question with empty/over-1,000-char prompt — schema.md §"Survey entity spec" InvalidArgument (implementation-defined; message MUST reference the offending bound)
CreateSurvey / EditSurvey multi-choice question with fewer than 2 or more than 20 options, or any option.label empty / over 200 chars — schema.md §"Survey entity spec" InvalidArgument (implementation-defined; message MUST reference the offending bound)
EditSurvey no survey exists yet for the playtest (call CreateSurvey first) — §4.7 FailedPrecondition (implementation-defined; message SHOULD reference creating the first version)
EditSurvey a question.id (or option.id) does not match any entry on the current version, or appears twice in the request — schema.md §"Survey entity spec" InvalidArgument (implementation-defined; message MUST reference the offending id and whether it was unknown or duplicated)
GetSurvey playtest has no survey configured (or Playtest.surveyId dangling) — §4.7 / schema.md NotFound (empty / standard NotFound)
SubmitSurveyResponse calling player has no applicant row yet (must signup first) — §4.1 step 8 FailedPrecondition (implementation-defined; message SHOULD reference signup)
SubmitSurveyResponse applicant is not APPROVED — §5.6 FailedPrecondition (implementation-defined; message MUST reference APPROVED)
SubmitSurveyResponse NDA re-acceptance required (applicant.ndaVersionHash != playtest.currentNdaVersionHash) — §5.6 FailedPrecondition (implementation-defined; message MUST reference NDA)
SubmitSurveyResponse playtest has no survey configured — §5.6 FailedPrecondition (implementation-defined; message SHOULD reference no-survey)
SubmitSurveyResponse submitted surveyId does not exist or does not belong to the playtest — §5.6 InvalidArgument (implementation-defined; message MUST reference the offending surveyId)
SubmitSurveyResponse answer questionId does not match the survey, is repeated, has the wrong type, or violates per-type bounds (text >4,000 chars; rating outside 1–5; multi-choice unknown / repeated option_id or many entries on a single-select question) — §5.6 InvalidArgument (implementation-defined; message MUST reference the offending bound)
ExchangeDiscordCode request missing or malformed code / redirect_uri — STATUS.md M1 phase 9.3 InvalidArgument (implementation-defined; message MUST reference the offending field name)
ExchangeDiscordCode AGS IAM rejected with error=invalid_grant (Discord code expired / already used / redirect_uri mismatch) — STATUS.md M1 phase 9.3 InvalidArgument (implementation-defined; message SHOULD propagate the AGS error_description byte-exact)
ExchangeDiscordCode AGS IAM responded HTTP 5xx with error=server_error and an error_description containing discord.com + invalid_grant (AGS wraps Discord 4xx invalid_grant as a 5xx) — STATUS.md M1 phase 9.4 InvalidArgument (implementation-defined; message SHOULD propagate the AGS error_description byte-exact so the embedded Discord marker reaches the client)
ExchangeDiscordCode AGS IAM rejected with error=unauthorized_client (backend confidential client lacks the Discord-grant scope) — STATUS.md M1 phase 9.3 Internal (implementation-defined; message SHOULD reference Discord federation misconfiguration but MUST NOT leak the AGS error_description)
ExchangeDiscordCode AGS IAM unreachable (network error / TCP reset / TLS failure) — STATUS.md M1 phase 9.3 Unavailable (implementation-defined; message SHOULD reference AGS IAM unreachability)
ExchangeDiscordCode AGS IAM responded HTTP 5xx with no discord.com + invalid_grant marker in the body (genuine AGS outage) — STATUS.md M1 phase 9.3 Unavailable (implementation-defined; message SHOULD reference upstream AGS unavailability)
ListAuditLog malformed page_token (does not decode to a (createdAt, id) cursor) — STATUS.md M3 phase 6 InvalidArgument page_token is malformed
ListAuditLog actor_filter is neither system nor a UUID — STATUS.md M3 phase 6 InvalidArgument (implementation-defined; message MUST reference actor_filter)
CreatePlaytest (ADT) one or more of adt_namespace / adt_game_id / adt_build_id missing or empty — PRD §4.8 / §5.1 InvalidArgument (implementation-defined; message MUST reference which of the three ADT identifier fields is missing)
CreatePlaytest (ADT) initial_code_quantity set — ADT has no code pool (PRD §4.8.5) InvalidArgument (implementation-defined; message SHOULD reference that initial_code_quantity is not valid for ADT)
CreatePlaytest (non-ADT) any adt_namespace / adt_game_id / adt_build_id / adt_fallback_download_url set when distribution_model is not ADT — PRD §5.1 InvalidArgument (implementation-defined; message MUST reference the offending adt_* field name and the actual distribution_model)
CreatePlaytest (ADT) adt_build_id does not belong to the (adt_namespace, adt_game_id) per adt.Client.ListBuilds — PRD §4.8 InvalidArgument (implementation-defined; message SHOULD reference that the build id is unknown to the linked ADT namespace)
CreatePlaytest (ADT) no adt_linkage row exists for the caller's studio_namespace + the requested adt_namespace — PRD §4.8.1 FailedPrecondition (implementation-defined; message SHOULD reference linking the ADT namespace first)
StartADTLink ADT_BASE_URL env var unset — PRD §5.9 / §4.8.2 FailedPrecondition (implementation-defined; message SHOULD reference the missing ADT_BASE_URL configuration)
StartADTLink backend's AGS service IAM JWT carries neither union_namespace nor namespace claim — PRD §4.8.1 FailedPrecondition (implementation-defined; message SHOULD reference that the backend's service token cannot be resolved to a studio namespace)
CompleteADTLink state does not match any row in adt_link_pending, or the row has expired (expires_at < now()) — PRD §4.8.2 InvalidArgument (implementation-defined; message MUST reference that the linking state is invalid or expired; message SHOULD NOT distinguish "unknown" from "expired" so probing the table is uninformative)
CompleteADTLink adt_namespace query param is missing or empty on the callback — PRD §4.8.2 InvalidArgument (implementation-defined; message MUST reference adt_namespace)
UnlinkADT adtLinkageId does not match any adt_linkage row (live or soft-deleted) for the caller's studio_namespace — PRD §4.8 NotFound (empty / standard NotFound; idempotent re-unlink against an already-deleted row is a no-op success, not this error)
RecoverADTLinkage adtNamespace missing or empty on the request — PRD §4.8 InvalidArgument adt_namespace is required
RecoverADTLinkage a live adt_linkage row for the caller's studio_namespace + the requested adt_namespace already exists — PRD §4.8 AlreadyExists adt linkage already exists for that namespace
RecoverADTLinkage ADT returned errorCode=99 ("Namespace is not registered") on the linkage probe (ListGames) — adt.ErrLinkageMissing; no orphan flag exists on ADT's side for this pair — PRD §4.8 / STATUS_M5.md Bug 4 FailedPrecondition no ADT-side linkage found for that namespace; use StartADTLink to create one
RecoverADTLinkage ADT returned errorCode=401 on the linkage probe — adt.ErrUnauthenticated; bearer token rejected by ADT — PRD §4.8 / STATUS_M5.md Bug 4 FailedPrecondition ADT rejected the backend service token; rotate AGS IAM client credentials and restart the backend
RecoverADTLinkage ADT returned errorCode=20001 on the linkage probe — adt.ErrPermissionDenied; token valid but route permission absent — PRD §4.8 / STATUS_M5.md Bug 4 FailedPrecondition backend service token lacks required ADT permission scope; ask ADT-eng to grant the missing permission
RecoverADTLinkage ADT returned a transient error (5xx-retry exhausted or 429) on the linkage probe — PRD §4.8 Unavailable (implementation-defined; message SHOULD reference ADT being temporarily unavailable)
ListADTBuilds / ListADTGames adtLinkageId does not match any live adt_linkage row for the caller's studio_namespace — PRD §4.7 / §4.8 / STATUS_M5.md B12 FailedPrecondition no ADT linkage matches this id for the caller's studio; link an ADT namespace first
ListADTBuilds / ListADTGames ADT returned 401 on the proxied adt.Client.ListBuilds / ListGames call (linkage flag missing on ADT side) — PRD §4.8 / STATUS_M5.md B12 FailedPrecondition adt linkage no longer exists or service token rejected, re-link required
ChangeADTBuild adt_game_id or adt_build_id missing or empty — PRD §4.8 / §5.1 InvalidArgument (implementation-defined; message MUST reference that adt_game_id and adt_build_id are required)
ChangeADTBuild playtest distribution_model is not ADT (build can only be repointed on ADT playtests) — PRD §4.8 / §5.1 FailedPrecondition (implementation-defined; message SHOULD reference that the build can only be changed on ADT playtests)
ChangeADTBuild adt_build_id does not belong to the (adt_namespace, adt_game_id) per adt.Client.ListBuilds (same verification CreatePlaytest runs) — PRD §4.8 InvalidArgument (implementation-defined; message SHOULD reference that the build id is not present under the adt_namespace / adt_game_id)
ChangeADTBuild no adt_linkage row exists for the caller's studio_namespace + the playtest's adt_namespace — PRD §4.8.1 FailedPrecondition no ADT linkage covers this studio + adt_namespace; link the ADT namespace first
ChangeADTBuild ADT returned 401 on the proxied adt.Client.ListBuilds verification (linkage flag missing on ADT side) — PRD §4.8 FailedPrecondition adt linkage no longer exists or service token rejected, re-link required
ChangeADTBuild playtest_id does not match a live Playtest row (not found or soft-deleted) — PRD §4.8 NotFound playtest not found
CheckADTBuild playtest distribution_model is not ADT (build health only applies to ADT playtests) — M5.C "build gone" surfacing FailedPrecondition (implementation-defined; message SHOULD reference that build health only applies to ADT playtests)
CheckADTBuild playtest_id does not match a live Playtest row (not found or soft-deleted) — M5.C NotFound playtest not found
CheckADTBuild ADT returned 401 on the IssueDownloadURL probe (linkage flag missing on ADT side) — M5.C FailedPrecondition adt linkage no longer exists or service token rejected, re-link required
CheckADTBuild ADT returned a transient 4xx/5xx on the IssueDownloadURL probe — M5.C. NB: errorCode=1003303402 ("build not found") is NOT an error here — it is a successful response with healthy=false and persisted adt_build_status='UNAVAILABLE' Unavailable (implementation-defined; message SHOULD reference ADT unavailability)
ApproveApplicant (ADT) ADT returned 401 on IssueDownloadURL (linkage flag missing on ADT side, or union_namespace claim shift) — PRD §4.8.3 FailedPrecondition adt linkage no longer exists or service token rejected, re-link required
ApproveApplicant (ADT) / GetADTDownloadInfo ADT returned errorCode=1003303402 ("build not found") on IssueDownloadURL (linkage intact; the build was deleted from ADT) AND playtest has no adt_fallback_download_url set — adt.ErrBuildNotFound; PRD §4.8.3 / STATUS_M5.md FailedPrecondition ADT build no longer exists; it may have been deleted from ADT. Set a fallback download URL or re-create the playtest with a current build.
ApproveApplicant (ADT) ADT returned 4xx/5xx on IssueDownloadURL (linkage row still present) AND playtest has no adt_fallback_download_url set — PRD §4.8.3 Unavailable (implementation-defined; message SHOULD reference ADT unavailability and the option to set a fallback URL)
GetADTDownloadInfo playtest distribution_model is not ADT (caller should be using GetGrantedCode) — PRD §4.7 FailedPrecondition (implementation-defined; message SHOULD reference using GetGrantedCode for non-ADT playtests)
GetADTDownloadInfo calling applicant is not APPROVED — PRD §4.8.4 / §6 Security FailedPrecondition (implementation-defined; message SHOULD reference APPROVED; identical shape to GetGrantedCode's applicant-not-approved error so distribution-model probing via this RPC is not informative)
GetCodePool playtest distribution_model is ADT (no code pool) — PRD §5.5 / §4.8.5 FailedPrecondition (implementation-defined; message SHOULD reference that ADT playtests have no code pool to manage)
UploadCodes / TopUpCodes / SyncFromAGS playtest distribution_model is ADT — PRD §5.5 / §4.8.5 FailedPrecondition (implementation-defined; message SHOULD reference that ADT playtests have no code pool to manage)
CreatePlaytest / EditPlaytest banner_image_url set but not parseable as an https://... URL — PRD §5.1 InvalidArgument banner_image_url must be an https URL
CreatePlaytest / EditPlaytest platforms array is empty — PRD §5.1 InvalidArgument platforms must include at least one platform
CreatePlaytest / EditPlaytest platforms contains a value outside {WINDOWS, MACOS, PS5, XBOX_SERIES, LINUX} — PRD §5.1 InvalidArgument (implementation-defined; message MUST reference the offending platform value)
CreateAnnouncement subject is empty (length 0) — PRD §5.4 "Bulk announcements" InvalidArgument announcement subject must not be empty
CreateAnnouncement message is empty (length 0) — PRD §5.4 "Bulk announcements" InvalidArgument announcement message must not be empty
CreateAnnouncement subject longer than ANNOUNCEMENT_MAX_SUBJECT_LEN (default 200) — PRD §5.4 / §5.9 InvalidArgument announcement subject must be at most 200 characters
CreateAnnouncement message longer than ANNOUNCEMENT_MAX_MESSAGE_LEN (default 4000) — PRD §5.4 / §5.9 InvalidArgument announcement message must be at most 4000 characters
CreateAnnouncement send_to_filter not in {ALL, APPROVED_ONLY, PENDING_ONLY} — PRD §5.4 "Bulk announcements" InvalidArgument (implementation-defined; message MUST reference the offending send_to_filter value)
CreateAnnouncement playtest status = CLOSED — PRD §5.4 "Bulk announcements" FailedPrecondition playtest is closed; announcements can no longer be sent
GetPlaytestParticipants status_filter neither empty nor one of {PENDING, APPROVED, REJECTED} — PRD §5.4 / §4.7 InvalidArgument (implementation-defined; message MUST reference status_filter)

Rows marked "implementation-defined" fix the gRPC code contractually; the exact message string may be refined during implementation but MUST reference the cited condition. All other rows are byte-exact and MUST match verbatim.