You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Measured on origin/main@f4e741bd1 (re-confirmed on ae4cfcce7). Filed unassigned from the #12260 dev seat; not a regression from #12260 — see the last section.
The measurement
classifyDataError's declared-status 4xx arm ships the producer's message verbatim:
The sharing middleware's by-id write refusal declares { code: 'FORBIDDEN', status: 403 }, so it takes exactly this arm. Its thrown message is the ADR-0111 CODE: message idiom, and the whole thing — machine prefix included — becomes the flat body's human-readable error, which Console and the reporting deployment's own client render verbatim.
Pinned byte-for-byte by tests that assert the prefix survives:
packages/rest/src/rest-4xx-message-truncation.test.ts:123 — expect(r.body.error).toBe(msg) where msg starts FORBIDDEN:
respondSharingError's ADR-0111 prefix arm, same file
And rest-server.ts's own #8111 comment above that arm states:
The prefix is a SERVER-INTERNAL service→REST derivation: it is stripped below and never reaches the wire, so no consumer can read it
That is true for that door and not true for /data. The same refusal therefore reaches a client with the prefix on one route and without it on another — the door-disagreement shape #7525 / #8016 / #11588 keep producing.
Why it is worth a card now rather than before
#12260 converted the sharing write denial's sentence onto the Operation Message Catalog, so what a zh-CN user now reads on /data is:
FORBIDDEN: 您无权修改或删除这条记录,如需修改请联系该记录的负责人或管理员。
The actionable half is localized human language; the machine token glued in front of it is now the only non-human fragment left in the user's face. Before that conversion the whole sentence was English, so the prefix was not the salient part.
Not a regression, and deliberately out of #12260's scope
The prefix rode in front of the old English sentence identically — nothing about its handling moved. It is left alone there on purpose: the fence on that card was that the prefix is wire contract and must not be shadowed, and changing which bytes /data ships is a REST envelope decision, not a plugin one. Any fix moves the two pinned assertions above, which are legitimate wire-behaviour tests today.
Options, not a recommendation
Strip the CODE: prefix in the declared-4xx arm, matching the share door. Changes the flat 4xx body for every producer using the idiom, and moves both pinned tests.
Rule that the prefix in error is intended on /data and correct the #8111 comment, which currently asserts the opposite.
Option 2 looks cheapest and least contract-moving, but which door is right is an envelope decision for the maintainer rather than something a dev seat should pick.
Measured on
origin/main@f4e741bd1(re-confirmed onae4cfcce7). Filed unassigned from the #12260 dev seat; not a regression from #12260 — see the last section.The measurement
classifyDataError's declared-status 4xx arm ships the producer's message verbatim:packages/rest/src/error-response.ts:1019-1033The sharing middleware's by-id write refusal declares
{ code: 'FORBIDDEN', status: 403 }, so it takes exactly this arm. Its thrown message is the ADR-0111CODE: messageidiom, and the whole thing — machine prefix included — becomes the flat body's human-readableerror, which Console and the reporting deployment's own client render verbatim.Pinned byte-for-byte by tests that assert the prefix survives:
packages/rest/src/rest-4xx-message-truncation.test.ts:123—expect(r.body.error).toBe(msg)wheremsgstartsFORBIDDEN:packages/rest/src/rest-5xx-status-passthrough.test.ts:301—expect(r.body).toEqual({ error: msg, code: 'FORBIDDEN', object: 'showcase_inquiry' })The two doors disagree, and one of them says so in prose
The share-route family and
handleApprovalErrorboth strip it:packages/rest/src/rest-server.ts:10867—res.status(status).json({ code, error: msg.replace(/^[A-Z_]+:\s*/, '') })respondSharingError's ADR-0111 prefix arm, same fileAnd
rest-server.ts's own#8111comment above that arm states:That is true for that door and not true for
/data. The same refusal therefore reaches a client with the prefix on one route and without it on another — the door-disagreement shape #7525 / #8016 / #11588 keep producing.Why it is worth a card now rather than before
#12260 converted the sharing write denial's sentence onto the Operation Message Catalog, so what a zh-CN user now reads on
/datais:FORBIDDEN: 您无权修改或删除这条记录,如需修改请联系该记录的负责人或管理员。The actionable half is localized human language; the machine token glued in front of it is now the only non-human fragment left in the user's face. Before that conversion the whole sentence was English, so the prefix was not the salient part.
Not a regression, and deliberately out of #12260's scope
The prefix rode in front of the old English sentence identically — nothing about its handling moved. It is left alone there on purpose: the fence on that card was that the prefix is wire contract and must not be shadowed, and changing which bytes
/dataships is a REST envelope decision, not a plugin one. Any fix moves the two pinned assertions above, which are legitimate wire-behaviour tests today.Options, not a recommendation
CODE:prefix in the declared-4xx arm, matching the share door. Changes the flat 4xx body for every producer using the idiom, and moves both pinned tests.erroralone and have the producers markuserMessage(the rest:respondSharingError's nested re-dress also dropsuserMessageand the producer's structured context that/datacarries for the same throw #12669 channelwithDeclaredUserMessagealready puts on the flat body top level aterror-response.ts:569-571). Strictly additive on the wire; needs each emitter to opt in.erroris intended on/dataand correct the#8111comment, which currently asserts the opposite.Option 2 looks cheapest and least contract-moving, but which door is right is an envelope decision for the maintainer rather than something a dev seat should pick.