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
{{ message }}
Repository navigation
isMissingTableError's read-table check compares an object API name against a federated object's remoteName — a genuinely absent external remote now reads as loud, not benign #13438
Found while implementing #13324 (PR #13437); out of that card's scope, filed unassigned for triage. It is a residual of that repair, not a pre-existing defect.
isMissingTableError(error, readObject) now refuses the benign "table not provisioned yet" verdict when the dialect phrase names a relation other than the one the caller read. Call sites pass the object API name they were reading.
The gap
For a federated (external) object, the object API name is not the name the driver puts in the SQL. SqlDriver.registerExternalObject records external.remoteName in physicalTableByObject, and getBuilder targets that:
So when a federated object declares external: { remoteName: 'legacy_orders' } and that remote table is genuinely absent, the driver raises a phrase naming legacy_orders while the call site declares the object name (say crm_order). The names do not match, so the repaired predicate answers not benign for what is in fact a genuine missing table.
The comparison folds away schema/database qualifiers, the legacy namespace__short prefix and case, but it cannot fold away an arbitrary remoteName — nothing at the call site knows the mapping, which lives on the driver instance.
Reach
Only the call sites that read an arbitrary, caller-named object can hit this — a federated object is never one of the fixed sys_* reads:
ObjectQL.reportFindFailure — log level only, no data consequence
Severity, honestly
The failure direction is the loud one: a genuinely-unprovisioned federated remote surfaces as an error instead of being treated as truthful emptiness. Per the module's own docblock that is the cheap direction ("one extra error line" vs silent data loss), and #13324's ruling explicitly prefers it when the measurement is ambiguous. So this is a narrowing, not a corruption — but it IS a behaviour change for federated objects that nobody asked for, and it should be either closed or consciously accepted.
Not measured against a live federated deployment — derived from the mapping code and the call sites. Whether any shipped federated object also carries autonumber or inbound references (the two paths with a data consequence) is worth establishing before grading this.
Options, not decided here
Let the predicate take the resolved physical name. The engine's resolveObjectName does not consult the driver's physicalTableByObject, so this needs a driver-side accessor.
Let the driver declare the table it targeted on the error envelope. backendStatementFaultError(object, cause) already exists in packages/drivers/driver-sql/src/sql-driver.ts and knows both names; the predicate would prefer a declared name over the caller's. This is the cleanest shape and removes the parameter from the narrow paths entirely, but it touches this lane's serial hot file and only helps drivers that adopt it.
Accept and document: for external objects, a missing remote surfaces loudly.
Anchoring. All three candidate fix sites are one lane: option 1 lands in packages/objectql (engine accessor), option 2 in packages/drivers/driver-sql (backendStatementFaultError), option 3 is docs on the predicate. objectql and drivers/* are both domain:engine after the 2026-08-19 lane merge, so the option choice does not move the lane — it is the lane PM's to make.
Grade p3, and the card argues its own grade correctly. The failure direction is the loud one: a genuinely-absent federated remote surfaces as an error rather than as truthful emptiness. Per the module's own docblock that is the cheap direction, and #13324's ruling prefers it when the measurement is ambiguous. Narrowing, not corruption.
⛔ Pre-dispatch premise, from the card's own open question — this must be discharged, not carried. Establish whether any shipped federated object exists, and whether one carries autonumber or inbound references (seedAutonumber and the cascade-delete dependents probe are the only two of the four listed call sites with a data consequence; reportFindFailure is log-level only and SeedLoaderService is boot-time). If the answer is zero, option 3 (accept and document) is the honest close and this card is a docs edit. If non-zero, the grade moves and option 2 becomes the shape to argue for.
Recording the premise rather than guessing it: I did not run that census, because "is any federated object shipped" is a deployment question, not a git grep — the tree can only show that the code path exists, which the card already established.
The measurement this card says is owed before grading — done, with controls. Lane PM triage; ⛔ no code touched, no option chosen.
The card states it plainly:
Whether any shipped federated object also carries autonumber or inbound references (the two paths with a data consequence) is worth establishing before grading this.
Measured on origin/main. Answer: neither path is exercised by any shipped federated object.
Both are documented read-only ADR-0015 federation demos.
Autonumber — zero, and the control fired
Neither declares an autonumber field. That zero is a reading, not a broken grep: the same pattern over the same corpus returns a hit in examples/app-showcase/src/data/objects/field-zoo.object.ts, so the search demonstrably finds autonumber where it exists.
Inbound references — zero, and the needle was established before trusting it
⚠️ My first attempt at this half was not a valid zero — the shell || bound to head, which succeeds on empty input, so "no hits" was an artifact rather than a measurement. Redone properly:
Establish how this corpus spells a reference: Field.lookup( — 13 occurrences across 9 files. (No reference_to / referenceTo / master_detail spellings appear in showcase objects at all.)
Control: that needle returns 9 files, so it works.
Query: references to showcase_ext_customer / showcase_ext_order from outside their own declaration files — 2 hits, both prose in examples/app-showcase/README.md (lines 179 and 191). No object declares a lookup at either.
What this does to the grading
The card's own severity reasoning was conditional on this: the failure direction is the loud one (an error line where truthful emptiness was intended), which the module's docblock calls the cheap direction and which #13324's ruling explicitly prefers when the measurement is ambiguous. The measurement is no longer ambiguous — no shipped federated object reaches seedAutonumber or the cascade-delete dependents probe, the two paths with a data consequence.
So option 3 (accept and document) is now the well-supported route, and option 2 in particular — which the card notes "touches this lane's serial hot file" and "only helps drivers that adopt it" — buys nothing measurable against shipped code today.
⚠️Scope of this measurement, stated rather than implied. It covers federated objects shipped in this repo. A customer-authored federated object could carry autonumber or an inbound lookup, and nothing here rules that out — this is "no shipped instance", not "cannot happen". If that possibility is what the grading should turn on, this measurement does not settle it.
Routing
Left in the decision box rather than dispatched: choosing between "accept the narrowing and document it" and "close it" is still a call about behaviour nobody asked to change, even with the blast radius now measured as zero in-repo. The deliverable under option 3 is small and mechanical once chosen — a docblock line at the predicate saying that for external objects a genuinely-missing remote surfaces loudly, and why.
Activity
os-warren commentedon Aug 31, 2026
Triage →
domain:engine· p3 · bug.Anchoring. All three candidate fix sites are one lane: option 1 lands in
packages/objectql(engine accessor), option 2 inpackages/drivers/driver-sql(backendStatementFaultError), option 3 is docs on the predicate.objectqlanddrivers/*are bothdomain:engineafter the 2026-08-19 lane merge, so the option choice does not move the lane — it is the lane PM's to make.Grade p3, and the card argues its own grade correctly. The failure direction is the loud one: a genuinely-absent federated remote surfaces as an error rather than as truthful emptiness. Per the module's own docblock that is the cheap direction, and #13324's ruling prefers it when the measurement is ambiguous. Narrowing, not corruption.
⛔ Pre-dispatch premise, from the card's own open question — this must be discharged, not carried. Establish whether any shipped federated object exists, and whether one carries autonumber or inbound references (
seedAutonumberand the cascade-delete dependents probe are the only two of the four listed call sites with a data consequence;reportFindFailureis log-level only andSeedLoaderServiceis boot-time). If the answer is zero, option 3 (accept and document) is the honest close and this card is a docs edit. If non-zero, the grade moves and option 2 becomes the shape to argue for.Recording the premise rather than guessing it: I did not run that census, because "is any federated object shipped" is a deployment question, not a
git grep— the tree can only show that the code path exists, which the card already established.Generated by Claude Code
zhuangjianguo commentedon Aug 31, 2026
The measurement this card says is owed before grading — done, with controls. Lane PM triage; ⛔ no code touched, no option chosen.
The card states it plainly:
Measured on
origin/main. Answer: neither path is exercised by any shipped federated object.What ships
Exactly two objects declare
external.remoteName:showcase_ext_customercustomersexamples/app-showcase/src/data/objects/external/customer.object.tsshowcase_ext_orderordersexamples/app-showcase/src/data/objects/external/order.object.tsBoth are documented read-only ADR-0015 federation demos.
Autonumber — zero, and the control fired
Neither declares an autonumber field. That zero is a reading, not a broken grep: the same pattern over the same corpus returns a hit in
examples/app-showcase/src/data/objects/field-zoo.object.ts, so the search demonstrably finds autonumber where it exists.Inbound references — zero, and the needle was established before trusting it
||bound tohead, which succeeds on empty input, so "no hits" was an artifact rather than a measurement. Redone properly:Field.lookup(— 13 occurrences across 9 files. (Noreference_to/referenceTo/master_detailspellings appear in showcase objects at all.)showcase_ext_customer/showcase_ext_orderfrom outside their own declaration files — 2 hits, both prose inexamples/app-showcase/README.md(lines 179 and 191). No object declares a lookup at either.What this does to the grading
The card's own severity reasoning was conditional on this: the failure direction is the loud one (an error line where truthful emptiness was intended), which the module's docblock calls the cheap direction and which #13324's ruling explicitly prefers when the measurement is ambiguous. The measurement is no longer ambiguous — no shipped federated object reaches
seedAutonumberor the cascade-delete dependents probe, the two paths with a data consequence.So option 3 (accept and document) is now the well-supported route, and option 2 in particular — which the card notes "touches this lane's serial hot file" and "only helps drivers that adopt it" — buys nothing measurable against shipped code today.
Routing
Left in the decision box rather than dispatched: choosing between "accept the narrowing and document it" and "close it" is still a call about behaviour nobody asked to change, even with the blast radius now measured as zero in-repo. The deliverable under option 3 is small and mechanical once chosen — a docblock line at the predicate saying that for external objects a genuinely-missing remote surfaces loudly, and why.
Generated by Claude Code