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
Found while implementing #11718 (draft PR #12280), which aligned /analytics/dataset/query's declared-5xx arm to /data's. Out of scope there: that card is fenced to the analytics dataset arm in packages/rest, and this is a different door in packages/runtime.
⚠️Derived from source, not driven end-to-end. Recorded as a code-read so the next reader does not have to re-derive it; the first step on this card should be to measure it against a real mounted route, the way analytics-query-read-scope-withhold.test.ts already does for the code half.
The divergence
The two doors disagree on which declared 5xx gets its prose withheld.
packages/rest/src/error-response.ts — the /data arm (now shared as declaredServerFaultAnswer, PR #12280) withholds the message for any declared 5xx, whether or not a code rides along:
packages/runtime/src/dispatcher-plugin.ts — errorResponseBase, which /analytics/query and the other dispatcher exits use, gates the withhold on declaresServerFaultor a phrasing heuristic:
constmessage=declaresServerFault(err)||(httpStatus>=500&&looksLikeInternalErrorLeak(raw))
? INTERNAL_ERROR_MESSAGE
: raw||'Internal Server Error';
declaresServerFault is status >= 500and a non-empty string code (packages/types/src/error-leak.ts). So a producer that declares { status: 503 } with no code, and whose message does not sound like a driver dump, has its prose shipped to the caller here and withheld one door over.
Why this is the same class #5811 closed, one case narrower
#5811's own argument is that looksLikeInternalErrorLeak is a heuristic over SQL/driver phrasing, so it closes an exit only against faults that sound like a driver — measured, all eleven read-scope-sql shapes return FALSE from it. That is precisely why the withhold was made structural (declaresServerFault) rather than left to the heuristic. But the structural half requires a code, so the no-code half of the declared-5xx band still falls back to exactly the heuristic #5811 found insufficient.
error-response.ts documents the no-code case deliberately for the code field ("a half-declaration is honoured for the half that was declared and nothing is invented for the half that was not") — that reasoning is about inventing a code, and does not obviously extend to shipping the prose.
Whether any live producer declares a 5xx with no code and a non-driver-sounding message. Unmeasured — the population may be empty, which would make this a latent seam rather than a live leak, and that measurement should probably come first.
Found while implementing #11718 (draft PR #12280), which aligned
/analytics/dataset/query's declared-5xx arm to/data's. Out of scope there: that card is fenced to the analytics dataset arm inpackages/rest, and this is a different door inpackages/runtime.analytics-query-read-scope-withhold.test.tsalready does for the code half.The divergence
The two doors disagree on which declared 5xx gets its prose withheld.
packages/rest/src/error-response.ts— the/dataarm (now shared asdeclaredServerFaultAnswer, PR #12280) withholds the message for any declared 5xx, whether or not acoderides along:packages/runtime/src/dispatcher-plugin.ts—errorResponseBase, which/analytics/queryand the other dispatcher exits use, gates the withhold ondeclaresServerFaultor a phrasing heuristic:declaresServerFaultisstatus >= 500and a non-empty stringcode(packages/types/src/error-leak.ts). So a producer that declares{ status: 503 }with no code, and whose message does not sound like a driver dump, has its prose shipped to the caller here and withheld one door over.Why this is the same class #5811 closed, one case narrower
#5811's own argument is that
looksLikeInternalErrorLeakis a heuristic over SQL/driver phrasing, so it closes an exit only against faults that sound like a driver — measured, all elevenread-scope-sqlshapes return FALSE from it. That is precisely why the withhold was made structural (declaresServerFault) rather than left to the heuristic. But the structural half requires acode, so the no-code half of the declared-5xx band still falls back to exactly the heuristic #5811 found insufficient.error-response.tsdocuments the no-code case deliberately for the code field ("a half-declaration is honoured for the half that was declared and nothing is invented for the half that was not") — that reasoning is about inventing a code, and does not obviously extend to shipping the prose.Not established here
/analytics/query仍把 RLS 策略字段名回显给调用方 —— read-scope 拒收的泄漏在姐妹面上没堵,#5367 只堵了 dataset 路由 #5811's text argues the second only as far as it needed to.codeand a non-driver-sounding message. Unmeasured — the population may be empty, which would make this a latent seam rather than a live leak, and that measurement should probably come first.Region:
packages/runtime/src/dispatcher-plugin.ts,errorResponseBase's message ternary only.