Observation class (finding, no pm:queue). Found while implementing #7314 (PR #7384); filed unassigned rather than folded in, because #7314's scope is the libSQL/Turso arm and this is a sibling one.
Fact
packages/services/service-datasource/src/default-datasource-driver-factory.ts builds three drivers that ride in OPTIONAL packages, and all three used to answer an absent package with the fault and nothing else. #7314 / PR #7384 fixed one of them. The other two are unchanged:
sqlite-wasm driver requested but @objectstack/driver-sqlite-wasm is not installed (…).
mongodb driver requested but @objectstack/driver-mongodb is not installed (…).
Neither states the install command, neither states what happens next, and neither names the datasource that failed — while the turso arm beside them now states all three, and the host loader in @objectstack/runtime has stated them for libSQL since #5602. An admin who adds a mongo datasource in Setup and an admin who adds a libSQL one hit the same class of problem and get two different qualities of answer, decided by which driver they picked.
The remedy text is not the only thing missing: PR #7384 exports TURSO_DRIVER_PACKAGE / TURSO_DRIVER_INSTALL_COMMAND / missingTursoDriverMessage, so "how do I install the optional driver" now has one declaration for libSQL and none for the other two.
Why it is observation-grade rather than a defect
Nothing is broken. The failure fires at the right moment, is a refusal rather than a fallback, and interpolates the underlying import error — which is what keeps isUnbuiltWorkspaceFailure (connect-failure-remedy.ts) able to recognise a half-built checkout from these arms at all, since the re-throw drops the original code. What is missing is the operator's next step, which the sibling arm now provides.
Severity is deliberately not asserted; filed plainly for triage.
Shape a fix would take, if triaged
Generalise missingTursoDriverMessage into one builder over (driver id, package name, install command) and use it from all three arms, keeping the two discipline points PR #7384 landed under: name the datasource, and name exactly one fix with no escape-hatch env var (connect-failure-remedy.ts, #5794). Whether the pnpm add / yarn add parenthetical and the "refuses rather than falling back to another engine" clause generalise verbatim is worth a look — the consequence sentence is specific to a remote database being shadowed by a local one, which is exactly true for mongo and is a weaker statement for sqlite-wasm.
Related: #7314 (the libSQL half, fixed by PR #7384), #7243 (datasource.pool silently dropped in the same file — same "declared ≠ enforced" family, different surface).
⚠️ Unclaimed.
Generated by Claude Code
Observation class (
finding, nopm:queue). Found while implementing #7314 (PR #7384); filed unassigned rather than folded in, because #7314's scope is the libSQL/Turso arm and this is a sibling one.Fact
packages/services/service-datasource/src/default-datasource-driver-factory.tsbuilds three drivers that ride in OPTIONAL packages, and all three used to answer an absent package with the fault and nothing else. #7314 / PR #7384 fixed one of them. The other two are unchanged:Neither states the install command, neither states what happens next, and neither names the datasource that failed — while the
tursoarm beside them now states all three, and the host loader in@objectstack/runtimehas stated them for libSQL since #5602. An admin who adds a mongo datasource in Setup and an admin who adds a libSQL one hit the same class of problem and get two different qualities of answer, decided by which driver they picked.The remedy text is not the only thing missing: PR #7384 exports
TURSO_DRIVER_PACKAGE/TURSO_DRIVER_INSTALL_COMMAND/missingTursoDriverMessage, so "how do I install the optional driver" now has one declaration for libSQL and none for the other two.Why it is observation-grade rather than a defect
Nothing is broken. The failure fires at the right moment, is a refusal rather than a fallback, and interpolates the underlying import error — which is what keeps
isUnbuiltWorkspaceFailure(connect-failure-remedy.ts) able to recognise a half-built checkout from these arms at all, since the re-throw drops the originalcode. What is missing is the operator's next step, which the sibling arm now provides.Severity is deliberately not asserted; filed plainly for triage.
Shape a fix would take, if triaged
Generalise
missingTursoDriverMessageinto one builder over (driver id, package name, install command) and use it from all three arms, keeping the two discipline points PR #7384 landed under: name the datasource, and name exactly one fix with no escape-hatch env var (connect-failure-remedy.ts, #5794). Whether thepnpm add/yarn addparenthetical and the "refuses rather than falling back to another engine" clause generalise verbatim is worth a look — the consequence sentence is specific to a remote database being shadowed by a local one, which is exactly true for mongo and is a weaker statement forsqlite-wasm.Related: #7314 (the libSQL half, fixed by PR #7384), #7243 (
datasource.poolsilently dropped in the same file — same "declared ≠ enforced" family, different surface).Generated by Claude Code