Found while running the #14251 phase-1 consumer census (read-only). Recorded for triage; no severity asserted.
Measured by reading origin/main at a56baa2bdf. Located by symbol, not by line — the line numbers below are that commit's.
The shape
objectQLProvider has two consumers in packages/rest/src/rest-server.ts, and #13904 (PR #14250) repaired the slot for one of them:
| consumer |
line |
how it reaches the provider |
computeExecCtx, the authorization-input seam |
2361 |
wiredEngineOrLoud(Boolean(this.objectQLProvider), ...) — keeps the two facts apart (#13476) |
GET {basePath}/meta/object/:name/state/:field |
7453 |
await this.objectQLProvider(environmentId).catch(() => undefined) — re-collapses them |
The second one converts every rejection back into the same undefined a never-registered engine produces, three lines before the answer is chosen:
const ql = this.objectQLProvider
? await this.objectQLProvider(environmentId).catch(() => undefined)
: undefined;
const schema = (ql as any)?.registry?.getObject?.(name);
if (!schema) {
res.status(404).json({ error: { code: 'NOT_FOUND', message: 'Object not found' } });
⇒ on this route, an engine that was wired and failed to build and an engine that was never registered both answer 404 NOT_FOUND · "Object not found" — the same disguise #13476 measured at the package door (there it wore a 403), and the same one its sibling seam now answers 503 for.
Why this line is NEWLY load-bearing, and was not before
Before #13904 the shipped provider was try { ... } catch { return undefined; }, so it could not reject: the .catch at 7453 was dead code and the collapse happened one layer earlier. #13904 made the provider re-raise every unbranded rejection precisely so a consumer could see it. This consumer catches it back. So the repair reaches one of the slot's two consumers, and the other is unchanged by it.
⛔ Not a defect in #13904 — its card and its pins are scoped to the computeExecCtx seam, and they hold. This is the second consumer nobody enumerated.
A second, narrower observation at the same line
provider(environmentId).catch(...) attaches to the promise the call RETURNS, so it can only ever see a rejection. A host that wires a non-async provider — which the seam's declared type cannot prevent, and RestServer's constructor is the public wiring point — throws while the expression is still being evaluated, and the .catch is never reached. That is exactly the asymmetry seamOrUndefined was introduced to end (its docblock measures it at settingsServiceProvider: 200 when the provider was async, 401 when it was not).
Two provider call sites in rest-server.ts still carry the retired spelling:
rest-server.ts:7453 — objectQLProvider (above)
rest-server.ts:9286 — emailServiceProvider, in POST {basePath}/email/send
Every other provider call site in the file either goes through seamOrUndefined / wiredEngineOrLoud or wraps the call in a real try/catch, which sees both fault shapes.
⚠️ Neither is reachable from the shipped wiring today: both providers in rest-api-plugin.ts are declared async. This is residue of the #13280 class at an embedder-reachable seam, not a live wire defect.
Scope
Not folded into anything. #14251 phase 1 is read-only, and its file surface is the provider closures in rest-api-plugin.ts; both observations here are consumer-side, in rest-server.ts. The repair for the first is a one-line change of spelling at 7453 plus the ruling that goes with it — is "the engine is wired and broken" a 503 on a metadata read, as it already is on the package door — which is a per-consumer judgement and the reason this is a card and not a rider.
Found while running the #14251 phase-1 consumer census (read-only). Recorded for triage; no severity asserted.
Measured by reading
origin/mainata56baa2bdf. Located by symbol, not by line — the line numbers below are that commit's.The shape
objectQLProviderhas two consumers inpackages/rest/src/rest-server.ts, and #13904 (PR #14250) repaired the slot for one of them:computeExecCtx, the authorization-input seamwiredEngineOrLoud(Boolean(this.objectQLProvider), ...)— keeps the two facts apart (#13476)GET {basePath}/meta/object/:name/state/:fieldawait this.objectQLProvider(environmentId).catch(() => undefined)— re-collapses themThe second one converts every rejection back into the same
undefineda never-registered engine produces, three lines before the answer is chosen:⇒ on this route, an engine that was wired and failed to build and an engine that was never registered both answer
404 NOT_FOUND · "Object not found"— the same disguise #13476 measured at the package door (there it wore a 403), and the same one its sibling seam now answers503for.Why this line is NEWLY load-bearing, and was not before
Before #13904 the shipped provider was
try { ... } catch { return undefined; }, so it could not reject: the.catchat 7453 was dead code and the collapse happened one layer earlier. #13904 made the provider re-raise every unbranded rejection precisely so a consumer could see it. This consumer catches it back. So the repair reaches one of the slot's two consumers, and the other is unchanged by it.⛔ Not a defect in #13904 — its card and its pins are scoped to the
computeExecCtxseam, and they hold. This is the second consumer nobody enumerated.A second, narrower observation at the same line
provider(environmentId).catch(...)attaches to the promise the call RETURNS, so it can only ever see a rejection. A host that wires a non-asyncprovider — which the seam's declared type cannot prevent, andRestServer's constructor is the public wiring point — throws while the expression is still being evaluated, and the.catchis never reached. That is exactly the asymmetryseamOrUndefinedwas introduced to end (its docblock measures it atsettingsServiceProvider: 200 when the provider wasasync, 401 when it was not).Two provider call sites in
rest-server.tsstill carry the retired spelling:rest-server.ts:7453—objectQLProvider(above)rest-server.ts:9286—emailServiceProvider, inPOST {basePath}/email/sendEvery other provider call site in the file either goes through
seamOrUndefined/wiredEngineOrLoudor wraps the call in a realtry/catch, which sees both fault shapes.rest-api-plugin.tsare declaredasync. This is residue of the #13280 class at an embedder-reachable seam, not a live wire defect.Scope
Not folded into anything. #14251 phase 1 is read-only, and its file surface is the provider closures in
rest-api-plugin.ts; both observations here are consumer-side, inrest-server.ts. The repair for the first is a one-line change of spelling at 7453 plus the ruling that goes with it — is "the engine is wired and broken" a 503 on a metadata read, as it already is on the package door — which is a per-consumer judgement and the reason this is a card and not a rider.