QA-source: #9417 · api-backend.error-envelope-ledger · c1
Extracted at close-out of the #9296 QA wave (#9480). Designated for extraction by the Tier-2A reviewer of record — "two API-shape observations worth their own cards rather than burial in a run record". Subject sha e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd, stock showcase.
Observed
Every 401 across the API answers:
{"error":"UNAUTHENTICATED","message":"Authentication is required to access this endpoint."}The code sits in error, and there is no code key. Every other sampled error family answers {error: <message>, code: <CODE>} — VALIDATION_FAILED, PERMISSION_DENIED, OBJECT_NOT_FOUND, RECORD_NOT_FOUND, BATCH_NOT_ATOMIC and UNSUPPORTED_QUERY_PARAM all carry both keys, with error holding the human message.
Verified across route families in #9417: /data/:object, /data/:object/:id, /meta/object, /meta/agent|tool|skill, /reports.
Why it matters
A client keying on body.code — the shape the other six families teach — reads undefined for every authentication failure, and a client keying on body.error reads a message everywhere else and a code here.
It also cost coverage: #9333 records api-backend.error-envelope-ledgerc0 and c3 as partial precisely because the 401 sample carries no code, so neither its ledger membership nor its status mapping could be verified from the response.
Fix direction — not prescribed
Whether the answer is to add code: "UNAUTHENTICATED" alongside the existing keys, or to declare the 401 family's shape explicitly in the error ledger, is a triage/design call. The property worth pinning either way: one documented key identifies the code on every error family, 401 included.
No priority and no domain:* label — normal triage first-touch.
QA-source: #9417 · api-backend.error-envelope-ledger · c1
Extracted at close-out of the #9296 QA wave (#9480). Designated for extraction by the Tier-2A reviewer of record — "two API-shape observations worth their own cards rather than burial in a run record". Subject sha
e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd, stock showcase.Observed
Every 401 across the API answers:
{"error":"UNAUTHENTICATED","message":"Authentication is required to access this endpoint."}The code sits in
error, and there is nocodekey. Every other sampled error family answers{error: <message>, code: <CODE>}—VALIDATION_FAILED,PERMISSION_DENIED,OBJECT_NOT_FOUND,RECORD_NOT_FOUND,BATCH_NOT_ATOMICandUNSUPPORTED_QUERY_PARAMall carry both keys, witherrorholding the human message.Verified across route families in #9417:
/data/:object,/data/:object/:id,/meta/object,/meta/agent|tool|skill,/reports.Why it matters
A client keying on
body.code— the shape the other six families teach — readsundefinedfor every authentication failure, and a client keying onbody.errorreads a message everywhere else and a code here.It also cost coverage: #9333 records
api-backend.error-envelope-ledgerc0 and c3 aspartialprecisely because the 401 sample carries nocode, so neither its ledger membership nor its status mapping could be verified from the response.Fix direction — not prescribed
Whether the answer is to add
code: "UNAUTHENTICATED"alongside the existing keys, or to declare the 401 family's shape explicitly in the error ledger, is a triage/design call. The property worth pinning either way: one documented key identifies the code on every error family, 401 included.No priority and no
domain:*label — normal triage first-touch.