Filed unassigned while implementing the #11683 + #11684 fold. Out of scope there: the repair is in packages/types, outside that card's declared file surface.
Measured
ApiErrorSchema (packages/spec/src/api/contract.zod.ts) declares declaredCode:
declaredCode: z.string().optional().describe('The producer-declared code, verbatim, when it is not a member of the closed `code` vocabulary — the open, author-authored channel (app-specific spellings; ADR-0112, #9106)')
The shared nested-envelope writer cannot emit it. packages/types/src/response-envelope.ts:
exportfunctionsendError(res: EnvelopeResponse,status: number,code: ErrorCode,message: string,extra?: Pick<ApiError,'category'|'httpStatus'|'details'|'requestId'>,): void
declaredCode is not in that Pick, so no route answering through sendError can put it on the wire — it is a compile error to try.
Why it matters
ADR-0112's 2026-08-17 amendment (#9106, extended to the flat door by #9232) rules the demote platform-wide, in its own words: "error.code stays a closed vocabulary at every door. A thrown code that is not a member … is demoted to a declared sibling field, ApiError.declaredCode" — and it names the capability the channel exists to preserve: SandboxError carries a metadata app's own.code across the QuickJS boundary on purpose (#7867), so the author's spelling "still crosses the sandbox and still reaches the wire; it lands in the open channel rather than the closed one."
On a route answering the nested envelope it does not. The closed code still carries the derived member, so nothing invalid ships — the loss is silent and one-directional: the author's spelling is gone, and a consumer told by the ADR to read declaredCode finds nothing there.
Observed while routing the record-share family's refusals through the shared classification door: resolveThrownHttpError / demotedDeclaredCode produce the pair, the flat /data door carries both, and respondError (→ sendError) can only carry one. A sandboxed hook on a sys_record_share write is the reachable producer of a tenant-authored code there.
Not established here
- The blast radius. The seven modules on the shared pair (
storage-routes, settings-routes, admin-routes, external-datasource-routes, package-routes, i18n-service-plugin, share-link-routes) plus the record-share family all answer through sendError; which of them can actually catch a tenant-authored code was not censused. - Whether the fix is widening the
Pick or routing these bodies through resolveThrownHttpError wholesale. - Severity not judged.
Region: packages/types/src/response-envelope.ts, sendError's extra parameter.
Filed unassigned while implementing the #11683 + #11684 fold. Out of scope there: the repair is in
packages/types, outside that card's declared file surface.Measured
ApiErrorSchema(packages/spec/src/api/contract.zod.ts) declaresdeclaredCode:The shared nested-envelope writer cannot emit it.
packages/types/src/response-envelope.ts:declaredCodeis not in thatPick, so no route answering throughsendErrorcan put it on the wire — it is a compile error to try.Why it matters
ADR-0112's 2026-08-17 amendment (#9106, extended to the flat door by #9232) rules the demote platform-wide, in its own words: "
error.codestays a closed vocabulary at every door. A thrown code that is not a member … is demoted to a declared sibling field,ApiError.declaredCode" — and it names the capability the channel exists to preserve:SandboxErrorcarries a metadata app's own.codeacross the QuickJS boundary on purpose (#7867), so the author's spelling "still crosses the sandbox and still reaches the wire; it lands in the open channel rather than the closed one."On a route answering the nested envelope it does not. The closed
codestill carries the derived member, so nothing invalid ships — the loss is silent and one-directional: the author's spelling is gone, and a consumer told by the ADR to readdeclaredCodefinds nothing there.Observed while routing the record-share family's refusals through the shared classification door:
resolveThrownHttpError/demotedDeclaredCodeproduce the pair, the flat/datadoor carries both, andrespondError(→sendError) can only carry one. A sandboxed hook on asys_record_sharewrite is the reachable producer of a tenant-authored code there.Not established here
storage-routes,settings-routes,admin-routes,external-datasource-routes,package-routes,i18n-service-plugin,share-link-routes) plus the record-share family all answer throughsendError; which of them can actually catch a tenant-authored code was not censused.Pickor routing these bodies throughresolveThrownHttpErrorwholesale.Region:
packages/types/src/response-envelope.ts,sendError'sextraparameter.