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
finding(metadata-protocol): 30 refusal messages open with a bracketed tag that restates the code the same throw declares — the shape #12975 rules out, and it reaches the wire #16245
Found while removing [unanswerable_target] for #16145; recorded rather than fixed, because the remedy needs a ruling this seat may not make.
What is there
packages/metadata-protocol opens many refusal messages with a bracketed lowercase tag. Pairing every such throw site in protocol.ts and sys-metadata-repository.ts with the code that site declares:
tag
declared code
status
[invalid_request]
INVALID_REQUEST
400
[item_locked]
ITEM_LOCKED
403
[not_overridable]
NOT_OVERRIDABLE
403
[no_draft]
NO_DRAFT
404
[commit_not_found]
COMMIT_NOT_FOUND
404
[metadata_conflict]
METADATA_CONFLICT
409
[version_not_restorable]
VERSION_NOT_RESTORABLE
409
[invalid_metadata]
INVALID_METADATA
422
[writable_package_required]
WRITABLE_PACKAGE_REQUIRED
422
… and the rest
…
…
Every one of them is the lowercase restatement of the code the very same throw declares. Measured: of the 31 tagged throw sites across those two files that declare a code, 30 restate it this way. (The 31st was [unanswerable_target], whose code was NOT_IMPLEMENTED — that mismatch is exactly why it was in scope for #16145 and these are not.)
Why this is a row and not just a style note
The ruling behind #12975 (maintainer, 2026-08-29) on the /data door shipping FORBIDDEN: in front of a localized refusal is: ONE envelope semantics — error is HUMAN LANGUAGE, code is the MACHINE TOKEN — and a prefix is removed because the same fact already rides the code axis. These 30 tags are that condition exactly, by construction: each restates its own declared code.
They are not invisible. withoutDeclaredCodePrefix (packages/rest/src/error-response.ts) strips a prefix only when the message opens with the producer's declared code followed by a colon — INVALID_REQUEST: …. The bracketed lowercase spelling matches neither the casing nor the separator, so it is not stripped and reaches the caller in error.message.
Why it is a ruling and not a cleanup
⛔ Unlike #16145's single outlier, this family is documented, so removing it is a contract question rather than tidying:
packages/spec/src/api/protocol.zod.ts describes behaviour in these terms — e.g. the promotion field's text says the lookup "answers 404 [no_draft]", with the brackets.
That text is generated into content/docs/references/api/protocol.mdx, so the bracketed spelling is published documentation.
ADR-0010 and ADR-0112 both use this vocabulary, and sys_metadata_audit persists a code column whose documented example value is item_locked — a genuinely machine-readable axis using the same words.
So there is a real question underneath, and it is not "are these redundant" (measured: they are) but "is the bracketed opener load-bearing for any consumer, given the audit-row code column shares its vocabulary?" Three routes, none of them obviously right:
⛔ This was deliberately not ridden along on #16145's PR: that card's diff is one string literal at the single site whose tag was not a restatement, and folding 30 documented sites plus their spec descriptions and generated docs into it would have made a one-line prose fix into a contract change.
Measurement provenance
Derived at origin/maincbca47d09, in a dedicated worktree, with git grep using plain directory pathspecs and no ** globs. The pairing was produced by walking each bracketed-tag line and reading the nearest following code assignment within the same throw; one apparent extra mismatch was checked by hand and is a docblock line, not a throw. Firing controls on the same command and scope returned 5, 6 and 140 files, so the counts are readings rather than a broken pattern.
Found while removing
[unanswerable_target]for #16145; recorded rather than fixed, because the remedy needs a ruling this seat may not make.What is there
packages/metadata-protocolopens many refusal messages with a bracketed lowercase tag. Pairing every such throw site inprotocol.tsandsys-metadata-repository.tswith thecodethat site declares:code[invalid_request]INVALID_REQUEST[item_locked]ITEM_LOCKED[not_overridable]NOT_OVERRIDABLE[no_draft]NO_DRAFT[commit_not_found]COMMIT_NOT_FOUND[metadata_conflict]METADATA_CONFLICT[version_not_restorable]VERSION_NOT_RESTORABLE[invalid_metadata]INVALID_METADATA[writable_package_required]WRITABLE_PACKAGE_REQUIREDEvery one of them is the lowercase restatement of the code the very same throw declares. Measured: of the 31 tagged throw sites across those two files that declare a
code, 30 restate it this way. (The 31st was[unanswerable_target], whose code wasNOT_IMPLEMENTED— that mismatch is exactly why it was in scope for #16145 and these are not.)Why this is a row and not just a style note
The ruling behind #12975 (maintainer, 2026-08-29) on the
/datadoor shippingFORBIDDEN:in front of a localized refusal is: ONE envelope semantics —erroris HUMAN LANGUAGE,codeis the MACHINE TOKEN — and a prefix is removed because the same fact already rides thecodeaxis. These 30 tags are that condition exactly, by construction: each restates its own declared code.They are not invisible.
withoutDeclaredCodePrefix(packages/rest/src/error-response.ts) strips a prefix only when the message opens with the producer's declared code followed by a colon —INVALID_REQUEST: …. The bracketed lowercase spelling matches neither the casing nor the separator, so it is not stripped and reaches the caller inerror.message.Why it is a ruling and not a cleanup
⛔ Unlike #16145's single outlier, this family is documented, so removing it is a contract question rather than tidying:
packages/spec/src/api/protocol.zod.tsdescribes behaviour in these terms — e.g. the promotion field's text says the lookup "answers 404[no_draft]", with the brackets.content/docs/references/api/protocol.mdx, so the bracketed spelling is published documentation.ADR-0010andADR-0112both use this vocabulary, andsys_metadata_auditpersists acodecolumn whose documented example value isitem_locked— a genuinely machine-readable axis using the same words.So there is a real question underneath, and it is not "are these redundant" (measured: they are) but "is the bracketed opener load-bearing for any consumer, given the audit-row
codecolumn shares its vocabulary?" Three routes, none of them obviously right:CODE:prefix inside the user-facingerrorstring, so a localized refusal renders asFORBIDDEN: …in a toast #12975 rules and as finding(metadata-protocol): the unanswerable-target refusal opens its human message with a machine-shaped[unanswerable_target]tag that has no reader — and it is now wire-visible #16145 did for the outlier, and correct the.describe()text that spells them.[unanswerable_target]tag that has no reader — and it is now wire-visible #16145.Scope note
⛔ This was deliberately not ridden along on #16145's PR: that card's diff is one string literal at the single site whose tag was not a restatement, and folding 30 documented sites plus their spec descriptions and generated docs into it would have made a one-line prose fix into a contract change.
Measurement provenance
Derived at
origin/maincbca47d09, in a dedicated worktree, withgit grepusing plain directory pathspecs and no**globs. The pairing was produced by walking each bracketed-tag line and reading the nearest followingcodeassignment within the same throw; one apparent extra mismatch was checked by hand and is a docblock line, not a throw. Firing controls on the same command and scope returned 5, 6 and 140 files, so the counts are readings rather than a broken pattern.Generated by Claude Code