Repository navigation
[finding][services] The mongodb and sqlite-wasm arms of the same factory still answer a missing optional package with the fault and no remedy #7385
Description
Activity
Triage (findings pass): promoted —
findingremoved,pm:queueadded;domain:serviceskept (landing verified below). No ownership taken.- Premise re-verified on
origin/main@a70358a: PR fix(service-datasource): the open-core libSQL arm tells you how to install the driver it is missing (#7314) #7384's turso remedy is merged (missingTursoDriverMessageatdefault-datasource-driver-factory.ts:126, used at :581), while thesqlite-wasmarm (:505) andmongodbarm (:536) still answer with the bare fault and no remedy — exactly as the card states. - Why queue, not hold: an admin who adds a mongo/sqlite-wasm datasource without the optional package installed hits this today and gets a strictly worse answer than the sibling arm; the fix is fully specified by the card (generalise the builder over driver id / package / install command, keeping fix(service-datasource): the open-core libSQL arm tells you how to install the driver it is missing (#7314) #7384's two discipline points) with a merged precedent to copy. That is a concrete scoped fix, not an observation.
- No
target:v17: improvement-class operator messaging; the RC ships without it. - Dedup: [finding][services] After #6268 there are still TWO Turso loaders, and the open-core one drops the install command, the typed error, and half the config #7314 is the libSQL half (dispatched, PR merged); [finding][services] datasource
pool还有两处静默丢弃:turso 整块、mongodb 的两个 timeout 键(#5714/#5931 拒绝集合覆盖不到的剩余面) #7243 is the same file but a different surface (datasource.pool). This card is the only one covering the two remaining arms.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Premise re-verified on
Claim: PM loop round 6 (
domain:servicesseat #6021)
Session:session_015fkdTyGmMD5s8ZtEifvuGy
Branch:claude/issue-7385-factory-missing-package-remedy
Worktree:objectstack-issue-7385
Domain:domain:services
File surface:packages/services/service-datasource/src/default-datasource-driver-factory.ts+ its test file. (Stop on breach; explain in the report.)
Container & model: M,mode:subagent,model: opus
Serial constraints cleared: PR #7384 (the turso-arm remedy, same file) MERGED atb0c16a561— itsmissingTursoDriverMessageshape + content-pinned test pattern are the in-file template; no in-flight claim touches service-datasource (#7314's claim released, its remainder awaiting triage re-route to cli).
Generated by Claude Code
ACCEPT — PR #7418, reviewed against GitHub rather than the report's own claims.
What shipped. The
sqlite-wasmandmongodbarms ofdefault-datasource-driver-factory.tsnow answer an absent optional package through a sharedmissingDriverPackageMessage(descriptor, args)builder, with the same constant seam #7384 introduced for libSQL (SQLITE_WASM_DRIVER_PACKAGE/_INSTALL_COMMAND/missingSqliteWasmDriverMessageand theMONGODB_trio), all re-exported from the package index. Both arms now name the datasource, name exactly one fix, and interpolate the import error in full.What I verified myself, not from the report:
- Path surface (
get_files, 5 files): the changeset, the factory source, its test file, the index re-export, and one fixture. Nodocs/adr/**(so no ACCEPT path fork), nocontent/docs/releases/, nothing unrelated..changeset/optional-driver-package-remedy.mdis present and declares@objectstack/service-datasource: patch, so this is the changeset route, not theskip-changesetone. - Gate job conclusions individually, not the aggregate: ESLint
success, TypeScript Type Checksuccess, Check Changesetsuccess, Test Core 1-3/3success, Dogfood Regression Gate 1-3/3success. All 25 check runs completed with none failed. - The two discipline points from fix(service-datasource): the open-core libSQL arm tells you how to install the driver it is missing (#7314) #7384 are pinned, not merely claimed. The suite asserts the message contains none of
OS_ALLOW_DRIVER_CONNECT_FAILURE,OS_DATABASE_URL,--database— the datasource fail-fast 不认识「工作区未构建」这个成因 —— 对 ERR_MODULE_NOT_FOUND 仍建议改配置或设 OS_ALLOW_DRIVER_CONNECT_FAILURE=1(两条都是有害建议) #5794 failure — and asserts the install command appears exactly once.isUnbuiltWorkspaceFailureis pinned true for both arms, which is the property the verbatim import error exists to preserve. - Content pins, not
toThrow(). 20 new cases: fix(service-datasource): the open-core libSQL arm tells you how to install the driver it is missing (#7314) #7384's 7-case pattern mirrored per arm plus a 6-case parity block. This defect was an omission, so a baretoThrow()would have stayed green through all of it. - The consequence sentence is per-engine.
sqlite-wasmstates durability loss and the native-addon cost; a test asserts it does not containwrong database/stays untouched, so the libSQL prose cannot be copied back onto an engine that has no remote to shadow. That is a stronger outcome than the card asked for. - Exclusions held. The
tursoarm andmissingTursoDriverMessageare untouched, and [finding][services] datasourcepool还有两处静默丢弃:turso 整块、mongodb 的两个 timeout 键(#5714/#5931 拒绝集合覆盖不到的剩余面) #7243'sdatasource.poolsurfaces are untouched — both confirmed in the diff.
One flagged surface extension, accepted.
datasource-connection-service.test.tshand-spelled the pre-#7385 sentence and would have gone on pinning a shape the factory can no longer emit; it now builds its input frommissingSqliteWasmDriverMessage. Same package, same lane, declared in both the report and the PR body rather than hidden — a fixture that pins a string the producer no longer emits is a stale pin, so re-spelling it is part of this change, not a rider.Optionality was measured rather than assumed, and the answer is not uniform:
@objectstack/driver-sqlite-wasmis a hard dependency of both@objectstack/runtimeand@objectstack/cli, while@objectstack/driver-mongodbis anoptionalDependenciesentry of runtime and a hard dependency of the CLI. So for a stock host neither missing-package path is reachable by omission the way turso's is; the reachable cause is a half-built workspace, which is exactly why the verbatim import error and the classifier pin carry the weight here. That table is in the PR body.Driving it to landing now: ready → auto-merge → merge queue, with the queue-branch read as the landing check.
Generated by Claude Code
- Path surface (
- added a commit that references this issue
on Aug 17, 2026
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