Found while implementing #13905, which followed this module as its brand precedent. Recorded for triage; no severity asserted.
The shape
packages/core/src/security/authz-store-unavailable.ts documents its brand as a string-keyed own property chosen so that it survives structuredClone:
A string-keyed own property (not a Symbol.for registry key) so it survives
structuredClone, and so a duplicated copy of this module still brands identically.
The second half is correct and is the reason the choice is right. The first half is not true for an Error.
Measured
Node 22.22.2, on the box this repo builds on:
const e = new Error('x'); e.__brand = true; e.code = 'C';
const c = structuredClone(e);
// c.__brand === undefined c.code === undefined c.name === 'Error' c.message === 'x'
The structured-clone algorithm gives Error objects a dedicated serialization that carries name, message, stack and cause and drops every other own property — so both the brand and the ADR-0112 code are lost. For a plain object the doc claim would hold; for an Error subclass it does not.
Why it is worth recording rather than shrugging at
Nothing is broken today: isAuthzStoreUnavailableError is used on in-process rethrow paths (rethrowAuthzStoreUnavailable), where no cloning happens, so the predicate answers correctly everywhere it is actually called.
The cost is in propagation. This module is the governed precedent an author copies when they need a branded error, and the claim travels with it — the #13905 discriminator was written with that sentence copied verbatim and only lost it because the claim was measured before being repeated. A stated rationale that is false is also a trap in the other direction: it reads as a licence to send one of these across a worker or postMessage boundary and branch on the brand at the far end, which would silently answer false and fail open.
Suggested shape of the repair
Keep the property, keep the reasoning that earns it (a duplicated copy of the module still brands identically, which instanceof does not), and either drop the structuredClone clause or state the measured behaviour. No runtime change.
Related: #13905 (the module that would have inherited the claim; its own doc now states the measured behaviour instead).
Generated by Claude Code
Found while implementing #13905, which followed this module as its brand precedent. Recorded for triage; no severity asserted.
The shape
packages/core/src/security/authz-store-unavailable.tsdocuments its brand as a string-keyed own property chosen so that it survivesstructuredClone:The second half is correct and is the reason the choice is right. The first half is not true for an
Error.Measured
Node 22.22.2, on the box this repo builds on:
The structured-clone algorithm gives
Errorobjects a dedicated serialization that carriesname,message,stackandcauseand drops every other own property — so both the brand and the ADR-0112codeare lost. For a plain object the doc claim would hold; for anErrorsubclass it does not.Why it is worth recording rather than shrugging at
Nothing is broken today:
isAuthzStoreUnavailableErroris used on in-process rethrow paths (rethrowAuthzStoreUnavailable), where no cloning happens, so the predicate answers correctly everywhere it is actually called.The cost is in propagation. This module is the governed precedent an author copies when they need a branded error, and the claim travels with it — the #13905 discriminator was written with that sentence copied verbatim and only lost it because the claim was measured before being repeated. A stated rationale that is false is also a trap in the other direction: it reads as a licence to send one of these across a worker or
postMessageboundary and branch on the brand at the far end, which would silently answerfalseand fail open.Suggested shape of the repair
Keep the property, keep the reasoning that earns it (a duplicated copy of the module still brands identically, which
instanceofdoes not), and either drop thestructuredCloneclause or state the measured behaviour. No runtime change.Related: #13905 (the module that would have inherited the claim; its own doc now states the measured behaviour instead).
Generated by Claude Code