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
rest: the GENERIC declared-status passthrough still disagrees on object between the two error doors — plus one bespoke arm (RECORD_NOT_FOUND) still reachable from one door only #14725
Two residues of the #14541 door-disagreement class that #14541 does not close, filed rather than ridden on its PR: one was flagged by the contract review as out of scope ("noted for a card rather than as a condition"), the other was found by the drift guard that review's condition 3 required, and both are the same visible symptom with one decision behind them.
Residue 1 — the generic passthrough (contract-review probe H)
After #14541 the two doors agree for every error a bespoke arm classifies. They still disagree for an error that reaches the generic declared-status passthrough, because the two copies of that passthrough differ by one key:
classifyDataError's copy ends ...(object ? { object } : {}) — it appends the object name the door was called with.
resolveErrorResponse's 4xx arm has no such limb.
Measured on the #14541 branch, one error object, both doors:
error = { code: 'DUPLICATE_RECORD', status: 409 } // no `name`, so no bespoke arm
mapDataError(err, 'duly_note') 409 {"error":"…","code":"DUPLICATE_RECORD","object":"duly_note"}
sendThrownError(res, err, 'duly_note') 409 {"error":"…","code":"DUPLICATE_RECORD"}
Same class as #14541 — one refusal, two bodies, decided by which route caught it — one arm over.
Residue 2 — RECORD_NOT_FOUND is still a one-door arm
packages/rest/src/error-response.ts's record-level not-found arm sits BELOW the shared classification #14541 introduced:
Its producer declares a status, so the #14541 defect reaches it exactly as it reached the other ten: packages/core/src/utils/record-not-found.ts's recordNotFoundError sets code = 'RECORD_NOT_FOUND', status = 404 and object. So on every route reporting through handleRouteError / sendThrownError the declared-status passthrough answers first and object is dropped, while the single-record /data door reaches the arm and ships it.
It was not lifted with the other arms in #14541 for two reasons worth recording rather than rediscovering:
No → then classifyDataError's copy is the outlier and should lose the limb, which NARROWS single-record bodies that ship object today — a removal, not a widening, and a harder sell.
Neither, lift the arm instead → residue 2 alone closes by moving RECORD_NOT_FOUND's declared-code limb into structuredCodeAnswer (with the !isSandboxOrigin clause its new position would need, as OBJECT_NOT_FOUND and INVALID_FIELD carry), leaving its text limb where it is. Residue 1 stays open.
I did not census which routes actually pass an object argument at every call site, so the blast radius of the "yes" option is bounded above by "the data routes", not measured exactly.
Two residues of the #14541 door-disagreement class that #14541 does not close, filed rather than ridden on its PR: one was flagged by the contract review as out of scope ("noted for a card rather than as a condition"), the other was found by the drift guard that review's condition 3 required, and both are the same visible symptom with one decision behind them.
Residue 1 — the generic passthrough (contract-review probe H)
After #14541 the two doors agree for every error a bespoke arm classifies. They still disagree for an error that reaches the generic declared-status passthrough, because the two copies of that passthrough differ by one key:
classifyDataError's copy ends...(object ? { object } : {})— it appends the object name the door was called with.resolveErrorResponse's 4xx arm has no such limb.Measured on the #14541 branch, one error object, both doors:
Same class as #14541 — one refusal, two bodies, decided by which route caught it — one arm over.
Residue 2 —
RECORD_NOT_FOUNDis still a one-door armpackages/rest/src/error-response.ts's record-level not-found arm sits BELOW the shared classification #14541 introduced:Its producer declares a status, so the #14541 defect reaches it exactly as it reached the other ten:
packages/core/src/utils/record-not-found.ts'srecordNotFoundErrorsetscode = 'RECORD_NOT_FOUND',status = 404andobject. So on every route reporting throughhandleRouteError/sendThrownErrorthe declared-status passthrough answers first andobjectis dropped, while the single-record/datadoor reaches the arm and ships it.It was not lifted with the other arms in #14541 for two reasons worth recording rather than rediscovering:
/^Record … not found in …/iover the computedraw), and Routes exiting throughhandleRouteErroranswer the engine'sDUPLICATE_RECORDenvelope fromresolveErrorResponse's.statuspassthrough —fieldandobjectdropped,mapDataError's structured 409 arms never consulted #14541's stated boundary for the shared classification is declared code only — lifting a text sniff above the passthrough is whatresolveErrorResponse's own docblock argues against.handleRouteErroranswer the engine'sDUPLICATE_RECORDenvelope fromresolveErrorResponse's.statuspassthrough —fieldandobjectdropped,mapDataError's structured 409 arms never consulted #14541's wire delta was measured, published and contract-reviewed over a fixed set of codes. Adding an eleventh body change after that verdict would put an unreviewed delta into the PR whose whole claim is that the review saw every one.It is named in that PR's drift guard as a
known-gapentry citing this card, so the guard is green by disclosure rather than by omission.The one decision behind both
Should the bulk / metadata / UI door's declared-status passthrough carry
object?resolveErrorResponse's 4xx arm, and residue 2 closes with it for the common case (the caller passesreq.params?.objecton the data routes). It widens published bulk-door bodies by one key, which is the same Clause-② question Routes exiting throughhandleRouteErroranswer the engine'sDUPLICATE_RECORDenvelope fromresolveErrorResponse's.statuspassthrough —fieldandobjectdropped,mapDataError's structured 409 arms never consulted #14541 answered for nine codes.classifyDataError's copy is the outlier and should lose the limb, which NARROWS single-record bodies that shipobjecttoday — a removal, not a widening, and a harder sell.RECORD_NOT_FOUND's declared-code limb intostructuredCodeAnswer(with the!isSandboxOriginclause its new position would need, asOBJECT_NOT_FOUNDandINVALID_FIELDcarry), leaving its text limb where it is. Residue 1 stays open.Not claimed
handleRouteErroranswer the engine'sDUPLICATE_RECORDenvelope fromresolveErrorResponse's.statuspassthrough —fieldandobjectdropped,mapDataError's structured 409 arms never consulted #14541 and neither status is wrong.objectargument at every call site, so the blast radius of the "yes" option is bounded above by "the data routes", not measured exactly.