Found while verifying the 17.0.0-rc.1 checklist on #3909 (section A, "Datasource fail-fast #3741/#3758/#3826"). Verified on main @ 1ee48bc60 with a minimal purpose-built stack.
Setup
exportdefaultdefineStack({manifest: {id: 'com.rc1.probe', … },datasources: [{name: 'broken',driver: 'postgres',config: {url: 'postgres://nobody:secret123@127.0.0.1:1/nonexistent_db'}},],datasourceMapping: [{objectPattern: 'rc1_audit',datasource: 'broken'}],objects: [Widget,Audit,Trigger],});Port 1 on loopback with a nonexistent database — unreachable by construction.
Observed
- Boot succeeds, silently.
os serve --dev comes up healthy. The string broken appears zero times in the entire boot log — no connect attempt, no warning, no fail-fast. /ready answers 200{"status":"ready","state":"running"}.- The datasource listing reports the mapped datasource as
"status":"unvalidated" — honest that nothing was checked, but it is not a connect verdict:
{"name":"default","driver":"sqlite","status":"ok"},
{"name":"broken","driver":"postgres","status":"unvalidated"} - Worst part — the mapped object silently uses the DEFAULT datasource. Writing to
rc1_audit (the object mapped to broken) returns 201, reads back fine, and the row is physically in the default SQLite store:
POST /api/v1/data/rc1_audit {"name":"ds-probe",…} → 201
sqlite> select id,name from .objectstack/data/standalone.db rc1_audit;
lnK_IbrJnhDTUyKp|ds-probe
So an operator who routes an object to Postgres and gets the URL wrong is not told at boot, is not told at /ready, is not told at write time — and their data lands in a different database than the one they declared. They find out when they go looking in Postgres and it is empty.
Against what the checklist claims
- "a bound datasource with a bad URL fails the boot with an operator-readable error" — boot succeeds with no error at all.
- "
/ready 503s when a driver stops answering" — 200. - "Setup datasource list shows the real connect verdict + reason" — the verdict is
unvalidated; there is no reason because nothing connected.
I could not tell from the outside whether the mapping is being ignored (never routed) or resolved and silently falling back. Either way the user-visible outcome is the same and equally wrong; the fix differs, so worth determining internally. (objectPattern: 'rc1_audit' is an exact object name — if that spelling is not a valid pattern, an unmatched mapping rule should itself be an authoring error, which is the #4001-family posture this train applied everywhere else.)
Expected
A datasource that an object is actually mapped to is connected during boot; failure is a fail-fast with the operator-readable reason (and never a silent fallback to default). /ready reflects it. If lazy connection is deliberate, then the first read/write through the mapping must surface the connect failure rather than answering from another store.
Part of the #3909 rc.0 verification (section A).
Found while verifying the 17.0.0-rc.1 checklist on #3909 (section A, "Datasource fail-fast #3741/#3758/#3826"). Verified on
main@1ee48bc60with a minimal purpose-built stack.Setup
Port 1 on loopback with a nonexistent database — unreachable by construction.
Observed
os serve --devcomes up healthy. The stringbrokenappears zero times in the entire boot log — no connect attempt, no warning, no fail-fast./readyanswers 200{"status":"ready","state":"running"}."status":"unvalidated"— honest that nothing was checked, but it is not a connect verdict:{"name":"default","driver":"sqlite","status":"ok"}, {"name":"broken","driver":"postgres","status":"unvalidated"}rc1_audit(the object mapped tobroken) returns 201, reads back fine, and the row is physically in the default SQLite store:So an operator who routes an object to Postgres and gets the URL wrong is not told at boot, is not told at
/ready, is not told at write time — and their data lands in a different database than the one they declared. They find out when they go looking in Postgres and it is empty.Against what the checklist claims
/ready503s when a driver stops answering" — 200.unvalidated; there is no reason because nothing connected.I could not tell from the outside whether the mapping is being ignored (never routed) or resolved and silently falling back. Either way the user-visible outcome is the same and equally wrong; the fix differs, so worth determining internally. (
objectPattern: 'rc1_audit'is an exact object name — if that spelling is not a valid pattern, an unmatched mapping rule should itself be an authoring error, which is the #4001-family posture this train applied everywhere else.)Expected
A datasource that an object is actually mapped to is connected during boot; failure is a fail-fast with the operator-readable reason (and never a silent fallback to
default)./readyreflects it. If lazy connection is deliberate, then the first read/write through the mapping must surface the connect failure rather than answering from another store.Part of the #3909 rc.0 verification (section A).