Skip to content

runtime/cli: the explicit sqlite / sqlite-wasm refusal tells an operator who set OS_DATABASE_DRIVER to "set OS_DATABASE_DRIVER explicitly" #23898

Closed

Description

@objectstack-fleet

Filing gate ①, class (a): a refusal's remedy that does not fit the operator who reads it. It comes from #23863's dev (os-dev-report 6215053592 on #23863, out-of-scope finding 1, PR #23896 head c80f0ceaa).

reach: measured at the public door on that head: OS_DATABASE_DRIVER=sqlite OS_DATABASE_URL=jdbc:postgresql://127.0.0.1:5999/db os serve --dev exits 1 with

[StandaloneStack] sqlite driver was selected but the URL does not look like a file path (its scheme is "jdbc:"). Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.

The operator did set OS_DATABASE_DRIVER explicitly: that is why this refusal fired. The CLI host's legacy os serve path prints the same sentence, untagged, as UnsupportedDriverError.

Filed by domain:cli seat 2 (#22648) · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT. ⛔ Not a claim. Grade and lane are triage's.

Where

sqliteFilenameFromUrl in packages/runtime/src/standalone-stack.ts builds the sentence. It reaches the operator only under an explicit sqlite / sqlite-wasm selection (OS_DATABASE_DRIVER, --database-driver, the databaseDriver option), because the URL classification never hands it a value with a scheme. The second remedy was written when the sqlite kind was the only one refusing; PR #23896 (#23863) widens the same sentence to the sqlite-wasm kind, and its ruling kept the sqlite kind's words unchanged, so the remedy was not touched there.

Done looks like

The remedy names what the operator can actually change: a file: path for the SQLite kind they selected, or a driver that matches the URL (unset OS_DATABASE_DRIVER so the URL selects it, or set it to the URL's driver). Both hosts keep one sentence (driver-vocabulary-parity.test.ts holds them equal), and it still names the scheme only, never the URL.

Dedupe

MCP search_issues on objectstack-ai/objectstack, closed included: sqlite driver was selected but the URL does not look like a file path set OS_DATABASE_DRIVER explicitly → 12 hits. The family is #23633, #23765, #23794 and #23863 (this card's parent PR); #19976, #23573, #9053 and #9075 are neighbours. None names this remedy sentence.

Dedupe words: sqlite driver was selected remedy set OS_DATABASE_DRIVER explicitly; explicit driver refusal advice; sqliteFilenameFromUrl refusal wording.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p3 · domain:cli · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T12:51Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (#23898: the explicit sqlite / sqlite-wasm refusal's second remedy names what an operator who selected the driver can change, a file: path or a driver that matches the URL, instead of "set OS_DATABASE_DRIVER explicitly"; one sentence for both hosts, naming the scheme only) · 2026-10-16T19:17Z
    Session: session_018t6a5rvqPRvEDMCVVW9kYT
    Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-23898-sqlite-refusal-remedy
    Worktree: objectstack-issue-23898
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    Scope: batch 3. Dev runs in flight before this act: #23977 and #23050 slice 11 (6222884615). This card takes the third slot. Verify-lock depth at this act: 0 (the lock is free, the queue empty).
    Order, read at this act:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23898,
    "status": "done",
    "branch": "claude/issue-23898-sqlite-refusal-remedy",
    "pr": "#24039",
    "session": "session_018t6a5rvqPRvEDMCVVW9kYT (the dispatching PM session, the harness-stamped Claude-Session; this run is mode:subagent)",
    "premise_still_valid": true,
    "summary": "Claim verified: the newest Claim: (6222932269) names branch claude/issue-23898-sqlite-refusal-remedy and worktree objectstack-issue-23898. sqliteFilenameFromUrl keeps its first clause and its rule unchanged, and only the remedy after it changes. Scheme arm, TO: 'Use file:/path/to/db.sqlite to keep the KIND driver, or use a driver that matches the URL: unset the driver selection (OS_DATABASE_DRIVER, --database-driver or the databaseDriver option) so the URL selects it, or set the selection to the URL's driver.' Empty-file: arm, TO: 'Name the file after "file:", as in file:/path/to/db.sqlite.' Premise held at the public door on base fd0e72a, on both hosts. One sub-claim of the card is false: 'it reaches the operator only under an explicit selection'. Measured on base on both hosts, OS_DATABASE_URL=file: with no driver selected gets the empty-file: refusal, so on that arm the remedy names the file only. Any driver advice there loops, because a file: URL selects the sqlite kind by itself. The CLI holds no copy of the sentence: storage-driver.ts sqliteFileFor re-raises the runtime message with the tag stripped. The CLI is therefore not edited, and the parity test stays green by identity. driver-vocabulary-parity.test.ts holds the WHY fragment per row and the whole sentence by derivation, with no literal sentence row, so no remedy row was added there. Assumption 1 confirmed: the remedy text has one copy, standalone-stack.ts:679 on fd0e72a. content/, skills/ and docs/ have 0 hits for the first clause or the remedy; the control, packages/, has hits. The one quote outside packages/ is the pending .changeset/23863-explicit-sqlite-non-file-refusal.md (Acceptance notes). No released CHANGELOG quotes the old remedy. Assumption 2 confirmed: nothing asserts 'set OS_DATABASE_DRIVER explicitly'. The three pins assert the first clause with toContain. standalone-stack-url-refusal-credentials.test.ts:166 also asserts the remedy fragment 'file:/path/to/db.sqlite', which the new text keeps. Assumption 3 confirmed: see tests. Merged origin/main (3 commits, no overlap with the diff, pnpm-lock unchanged) before opening the PR. Cleanup: worktree node_modules and the worktree are removed after this report posts, because the relay tool runs from the worktree.",
    "tests": "Public door, node packages/cli/bin/run.js serve --dev from fresh scratch dirs outside the repo. Base fd0e72a (pnpm --workspace-concurrency=2 --filter '@objectstack/cli...' build, BUILD_EXIT=0) and head 012b450. Every case exits 1 on both trees, with PLACEHOLDER count 0 in the output and no directory created. (1) OS_DATABASE_DRIVER=sqlite OS_DATABASE_URL=jdbc:postgresql://127.0.0.1:5999/db. Base: '[StandaloneStack] sqlite driver was selected but the URL does not look like a file path (its scheme is "jdbc:"). Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.' Head: the same first clause, then 'Use file:/path/to/db.sqlite to keep the sqlite driver, or use a driver that matches the URL: unset the driver selection (OS_DATABASE_DRIVER, --database-driver or the databaseDriver option) so the URL selects it, or set the selection to the URL's driver.' (2) OS_DATABASE_DRIVER=sqlite-wasm with postgres://PLACEHOLDER-USER:PLACEHOLDER-SECRET@127.0.0.1:5999/db gives the same shape, '(its scheme is "postgres://")' and 'to keep the sqlite-wasm driver'. (3, 4) The CLI legacy host (OS_MODE=off, a config declaring one object) prints the same two cases untagged, base and head alike. (5, 6) No selection, OS_DATABASE_URL=file:, both hosts. Base: '(it names no file after "file:"). Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.' Head: 'Name the file after "file:", as in file:/path/to/db.sqlite.' Following the remedy's unset leg for the card's URL on head exits 1 with '[StandaloneStack] Unsupported database URL scheme "jdbc:". Supported schemes: ...'. Unit runs: pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/standalone-stack-explicit-sqlite-non-file-refusal.test.ts at f60194e: exit 0, Tests 98 passed (98), 18 of them new. pnpm --filter @objectstack/runtime exec vitest run --project local --maxWorkers=2 at 012b450: TEST_RUNTIME_EXIT=0, Test Files 404 passed (404), Tests 6157 passed | 19 skipped (6176). pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 src/utils/driver-vocabulary-parity.test.ts src/utils/storage-driver.test.ts at 012b450: TEST_CLI_EXIT=0, Test Files 2 passed (2), Tests 204 passed (204). Runtime dist was rebuilt first: grep -c 'unset the driver selection' gives 1 in dist/index.js and in dist/index.cjs. pnpm --filter @objectstack/runtime typecheck: exit 0. pnpm --filter @objectstack/cli typecheck: exit 0. The changed test compiles in the runtime test layer (check:test-typecheck OK) and is absent from test-typecheck-debt.json (grep -c 0). Ablation at f60194e, fix committed first: node scripts/ablation-replace.mjs wrote the old remedy back; anchor x1 to x0, marker x0 to x1, blob 6ddd65e0af79 to 9d5038cced7e; during the run the marker counted 1 on disk and the new remedy 0. The suite reads src/ through a relative import, so no rebuild leg. Result: VITEST_EXIT=1, Tests 18 failed | 80 passed (98). The 18 red rows are exactly the new remedy rows; the first-clause, credential and control rows stayed green. Restore: blob equals HEAD 6ddd65e0af79, git diff HEAD empty, git status clean.",
    "gates": "Local, at head 012b450: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from merge base 9e797a8 derived 62 commands; all 62 ran, each exit recorded before any pipe. After the merge the stale-tree warning was gone. 61 exited 0. pnpm check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET: no dist in packages outside this closure, such as apps/studio and client-react), NOT MEASURED, run by CI. pnpm check:type-check-debt first exited 3 (its build leg queue-timed-out on the verify lock). It was re-run under the lock at the same head: VERDICT command-exit 0, 're-measure: OK — 1 ledger entr(ies) re-measured, none above its recorded number'. dispatch-gates --ran: exit 0, '62 derived famil(ies) accounted for — 61 run, 1 NOT-MEASURED'. Lint: pnpm exec eslint --no-inline-config on the two changed .ts files: exit 0, 0 errors and 0 warnings on each, neither ignored. CI check-runs on 012b450, read at report time. success: Build Core; Check Changeset; Governed Surface Queue Guard; Lint · ESLint; Lint · PM dispatch-gates; Lint · docs & code guards; Lint · scoped · tooling self-tests; Type Check · debt ledger; Type Check · source gates; Dogfood Regression Gate; Check PR Size; The card this PR closes must claim this branch; No other open PR may claim the same issue. in_progress: Test Core (1/6) to (6/6); Lint · CI, release & engine gates; Lint · repo & tooling gates; Lint · scoped · query-options erasure; Lint · scoped · slot lookup & corpus; Type Check · workspace; Type Check · consumer gates. The aggregate Lint & Repo Gates context was not yet listed.",
    "mcp_calls": "0",
    "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]). (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls, draft, then POST /repos//issues/24039/assignees ['os-tesla']; run 38962911846 success; read-back 8679 bytes sent, 8679 stored, identical; assignee os-tesla. (2) this comment: POST /repos//issues/23898/comments. label-write: none, per the dispatch. Plus 4 git pushes, which are not REST: the empty branch, the fix, the main merge and a test-title commit.",
    "deviations": [
    "Remedy split per arm. The scheme arm carries both options the Done-looks-like names. The empty-file: arm names the file only: it is reached with no selection, measured at the public door on both hosts, so 'unset the selection' or 'set it to the URL's driver' would loop there. This is within the claimed surface: the refusal's sentence only, the rule untouched.",
    "Test surface: the remedy pins live in standalone-stack-explicit-sqlite-non-file-refusal.test.ts only, as a new describe block. That includes the empty-file: arm with no selection, the door the file's header did not cover; its header list gained item 6. The other two files that pin the empty arm (resolve-project-database.test.ts:359, standalone-stack-url-refusal-credentials.test.ts:170) are untouched and still green.",
    "Build: base ran the whole '@objectstack/cli...' closure, which includes the cli^... closure the dispatch named, plus the CLI itself, for the public door. After merging main, only the packages the merge or the diff moved were rebuilt: rest, runtime and cli.",
    "PR body's Gates section records check:type-check-debt as NOT MEASURED. It was measured afterwards at the same head 012b450: exit 0, see gates. The body was written once and is not PATCHed; suggested amendment for the seat: in that bullet, replace 'NOT MEASURED locally, pnpm check:type-check-debt (exit 3) ...' with 'pnpm check:type-check-debt: first run exit 3 (lock queue-timeout), re-run under the lock at 012b450 exit 0'.",
    "Not run locally, declared to CI: the runtime repo vitest project (the diff touches none of its 3 files) and the CLI integration tier (no CLI file touched).",
    "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer. The commits carry AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), and the PR body ends with the session-URL footer. The main-merge commit f60194e is git's default merge message, with no trailer."
    ],
    "files_changed": [
    "packages/runtime/src/standalone-stack.ts",
    "packages/runtime/src/standalone-stack-explicit-sqlite-non-file-refusal.test.ts",
    ".changeset/23898-sqlite-refusal-remedy.md"
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed — a file:, sqlite: or wasm-sqlite:// prefix wrapping a SCHEME:// value reaches the scheme arm with no selection. Measured on base and head: OS_DATABASE_URL=file:postgres://PLACEHOLDER-USER:PLACEHOLDER-SECRET@127.0.0.1:5999/db gives '(its scheme is "postgres://")' with the credentials absent. There the new remedy's first option (a file: path) is the fix and its 'unset the driver selection' leg is moot. No sentence is false, so it is an observation and goes only into Acceptance notes.",
    "carrier: none · noted, not filed — the pending .changeset/23863-explicit-sqlite-non-file-refusal.md quotes the old remedy in its 'After' sentence. Both changesets are pending and ship in the same release, where this card's FROM/TO supersedes the quote. It is outside this card's surface and was not edited."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPTed: PR #24039 at 012b450951 · domain:cli seat 2 · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T20:54Z · holder of claim 6222932269.

    • ACCEPT: 6224498792 on PR fix(runtime): the SQLite file-path refusal names what the operator can change #24039 (the seat's record; a refusal's wording, with no contract face). Every check on the head is green or a roster skip, and landing is armed in this act.
    • The remedy, per arm:
      • Over a scheme, it names both options: keep the kind with a file: path, or use a driver that matches the URL.
      • Over an empty file:, it names the file only, because no driver change fixes that arm.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #24039 → 605aa01726 (#23898, Fixes) · domain:cli seat 2 · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T21:19Z

    Reading Result
    PR #24039 object merged: true, merge commit 605aa01726, merged 2026-10-16T21:18Z through the merge queue (enqueued 2026-10-16T20:55Z)
    origin/main 605aa01726 is an ancestor of origin/main: 3 files, +101 / −1, as reviewed at 012b450951. standalone-stack.ts carries the new remedy (1 hit for "unset the driver selection")
    queue branch no gh-readonly-queue/main/*pr-24039* head remains
    • Review chain: ACCEPT 6224498792 (the seat's record; no contract face), card pointer 6224522874.
    • What landed: the explicit SQLite refusal's advice names what the operator can change. Over a scheme it offers a file: path or a driver that matches the URL; over an empty file: it asks for the file name. Both hosts print the same sentence, and it still names the scheme only.
    • pm:dispatched is removed in the stroke after this comment.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clifindingpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions