Skip to content

New datasource: the file path field holds a real :memory: value, and Test connection passes on the broken path it produces #30331

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

Filing gate: ③ the maintainer's direct order, verbatim: 「你发现的问题都立卡,安全问题总专用的安全密卡通道,需要进一步分析的进一步测试,还是没有把握的用决策卡。」 (2026-11-05). Found in a real-user browser walkthrough of Setup on main 04f36b63f8, with a test app and a local test deployment.

Business reason. An administrator connecting a company database relies on Test connection. A pass here means the connection is right, so a false pass sends them on to a connection with none of their data.

Reader. The UI lane dev for ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx, and the server lane for the test in packages/services/service-datasource.

Duplicates. Searched datasource filename memory prefilled (2 hits) and datasource test connection memory false (134 hits). They are QA run anchors and seat cards; none has this subject.

Measured

  1. Open 新建数据源 and leave the SQLite driver selected. The Filename box looks like a hint, and it already holds :memory: as its value.
  2. Click in and type a path. The box then reads :memory:/private/tmp/…/parts.db.
  3. POST /api/v1/datasources/test with that value answers ok: true.

A correct path that does not exist is refused properly, so the check works in that case.

I did not save a datasource with the broken value, so what it would then read is not measured.

Expected

  • The default is a placeholder, not a value, so typing replaces nothing by accident.
  • A filename that is neither exactly :memory: nor a usable path is refused by the test and by save, with a message that says why.

Activity

  1. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 · domain:server · pm:queue · 2026-11-05T07:11Z

    ⛔ Not a claim.

    • Read fresh. The new-datasource file path field holds a literal :memory: value, and Test connection passes on the broken path it produces. A false success, so p2. Platform first: service-datasource's test-connection must check the real target. The dialog default is the domain:ui half.

    Generated by Claude Code

  2. added
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF

    Claim: PM loop round 1
    Session: session_01Utp6CZMkHvuDeVYgTD73qF (seat) · dev card thread session_01Utp6Cb83ajcseWprEF9C9g
    Account: os-bill
    Branch: claude/project-thread-541rod (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-30331
    Domain: domain:server
    Seat: domain:server#4
    File surface: packages/services/service-datasource/** (the test-connection door and the datasource save, at the one place both pass through), their tests, one changeset. ⛔ packages/spec/**, docs/adr/**, .claude/**, repo-root AGENTS.md, ui/** (the dialog's :memory: default is the ui residue, recorded at landing), skills/** (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default judgment tier (opus) — dispatch-gates --tier: no path-derived mandate, effort: default
    Clause-②: yes (narrowing) — a SQLite filename that is neither exactly :memory: nor a usable path, accepted today by the test and save doors, is refused (the dev confirms the arm)
    Metadata-protocol: none
    Responsibility: the datasource test door answers ok: true for a SQLite filename such as ':memory:/private/tmp/…/parts.db' | none: the administrator is told the connection works (card, measured on main 04f36b63f8) | any administrator connecting a file database through Setup, whose field is prefilled with ':memory:'
    Thread-read: 6652062778
    Premise: holds
    Serial constraints cleared: no card in flight touches service-datasource (seats 3 and 5 confirmed).

    Dispatch order: /mnt/project-files/server-seat4/dispatch-30331.md (project shared folder). Ruling section: the card's Expected ("refused by the test and by save, with a message that says why") and triage audit 6652062778 ("Platform first"). PR Refs #30331 (server half), no closing keyword. A contract review at CONTRACT_REVIEW_TIER is owed before queue (narrowing).

    Posted 2026-11-05T07:50Z.

  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
    os-dev-report

    Status: done (server half). Draft PR #30395 carries Refs #30331 (server half), head cca010a64. The card stays open for the ui half.

    • Why :memory:/… passed. Every layer reads a name that starts with : as fileless (driver-sql resolveSqliteAbsentFileTarget / sqliteFilename, the wasm connection's isEphemeral), so the probe's missing-file refusal skipped it. better-sqlite3 then opens it as a relative path whose directory does not exist: connect() only warns and checkHealth() answers false, which the probe does not read as a failure. sqlite-wasm opens an ephemeral in-memory database.
    • What a saved one reads (measured). sqlite: every statement fails "Cannot open database because the directory does not exist". sqlite-wasm: writes succeed and are gone at the next connect or restart, with no error.
    • Fix. DatasourceAdminService.assertValidConfig, the one judgement the test, create and update doors share, also refuses a sqlite / sqlite-wasm filename that is empty, :-prefixed but not exactly :memory:, or a path that can be neither opened nor created (driver-sql's write-free judgement). Same envelope and code as every invalid config (400 DATASOURCE_ADMIN_ERROR; result.ok: false from the test). No new error code.
    • Kept. :memory:, an existing file, and a creatable missing path (test still refuses it per datasources: the draft probe POST /datasources/test creates the SQLite database file on disk although nothing is saved #27512, save accepts it) answer as before.

    Follow-up owed (seat files): the spec SqliteConfigSchema.filename refinement, so the build door and PUT /api/v1/meta/datasource/:name judge the same; ui residue: the dialog's :memory: value instead of a placeholder (DatasourceResourcePage.tsx).

    {
      "issue": 30331,
      "status": "done",
      "branch": "claude/project-thread-541rod",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30395",
      "session": "session_01Utp6Cb83ajcseWprEF9C9g",
      "premise_still_valid": true,
      "summary": "Server half only. Reproduced on main 8589756a through the real POST /api/v1/datasources/test: ':memory:/tmp/x30331/parts.db' answered ok:true for sqlite and sqlite-wasm. Cause: ':'-prefixed names are fileless to every layer, so the probe's absent-file refusal skipped it; native connect only warns and checkHealth false is read as ok; wasm opens an ephemeral database. A saved one fails every native statement, and on wasm loses every write at reconnect. The shared config gate (assertValidConfig, used by test, create and update) now refuses an empty, ':'-prefixed-but-not-':memory:', or unopenable/uncreatable filename with the value and reason, in the existing envelope.",
      "tests": "New src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts, 14 passed (7 per driver) through the real HonoHttpServer, admin routes, DatasourceAdminServicePlugin and default factory. Ablation (sqliteDatabaseFilenameIssue short-circuited, src imported by relative path, no dist leg): 8 failed / 6 passed, the 8 refusals red and the 6 controls green; restored, 14/14. Full @objectstack/service-datasource: 72 files, 1183 passed. Typecheck exit 0.",
      "gates": "dispatch-gates --commands derived 61 families; each run at head cca010a64 with exit recorded before any pipe: 61/61 exit 0 (check-plugin-teardown-shape --self-test after fetching 621a4876; check:dual-build-cjs-loads after the full build). --ran: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint exit 0. CI check-runs on #30395: not yet reported.",
      "dogfood_battery": "cca010a64 · os-verify-lock: VERDICT command-exit 0 · Test Files 419 passed / 3 skipped (422) · Tests 3492 passed / 36 skipped (3528) · no failures",
      "line_budget": "source +78 -9 (2 files), tests +222 (1 file), changeset +20 (1 file); 4 files, +320 -9",
      "deviations": "none against the dispatch. Save now also judges an unusable path (the dispatch's pin list asks for it); the empty filename is refused too, as the card's 'neither :memory: nor a usable path' covers it. The harness's model-named commit trailer was not used (repo hook); trailers are model-free.",
      "files_changed": [
        ".changeset/30331-sqlite-filename-neither-memory-nor-path.md",
        "packages/services/service-datasource/src/__tests__/sqlite-filename-neither-memory-nor-path.test.ts",
        "packages/services/service-datasource/src/datasource-admin-service.ts",
        "packages/services/service-datasource/src/sqlite-database-filename.ts"
      ],
      "mcp_calls": "2: mcp__github__issue_read x2 (get, get_comments); no GitHub write tool. Besides GitHub MCP: one subscribe_pr_activity on #30395 (session event subscription, writes nothing to GitHub)",
      "api_writes": "2 through the relay: pr_create #30395 (draft, no assignee, no labels, read-back identical) and this comment. Plus 1 git push to claude/project-thread-541rod (not REST)",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: b · Seam: spec:SqliteConfigSchema.filename ('Database file path, or :memory:') → runtime: build door and PUT /api/v1/meta/datasource/:name · reach: not measured at those doors (the admin doors are fixed here) · evidence: sqlite.zod.ts types filename as placeholderFree(z.string()) · dedupe words: sqlite filename refinement, :memory: prefix, meta datasource filename",
        "carrier: ui lane (#30331 stays open) · the New datasource dialog holds ':memory:' as a value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx)",
        "noted, not filed (no public input measured after this fix): DatasourceAdminServicePlugin.probe reports ok:true when the handle's ping (checkHealth) answers false — recorded in the PR's Acceptance notes"
      ]
    }

    Report taken 2026-11-05T09:34Z.


    Generated by Claude Code

  5. added
    domain:uiDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 5, 2026
  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF

    Landed · PR #30395 · server half · card stays open for the ui half

    Reading Value
    PR #30395 MERGED 2026-11-05T15:17Z, merge commit 22f0d656a; Refs #30331, so this card stays open. Seat record on head cca010a6 (BREAKING, not governed, ≤ 3000 lines; landed per pm-dispatch on the maintainer's 13:47Z word).
    main source packages/services/service-datasource/src/datasource-admin-service.ts:1382 const filenameIssue = await sqliteDatabaseFilenameIssue(driver, config);
    Landed A SQLite datasource whose filename the server cannot use (such as :memory:/…) is refused at create and at a config-touching edit, with a message naming the field.
    Remaining (ui) The New datasource dialog still holds :memory: as the Filename field's value instead of a placeholder (ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx). With this PR on main the mistake it invites is refused with a message instead of passing.
    Related The probe ignoring a false health check is #30407 (seat 3).

    Re-routed: domain:server → domain:ui, pm:dispatched → pm:queue, the os-bill assignee comes off with this comment.

    Posted 2026-11-05T15:22Z.

  7. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    Claim: PM loop round 9 · 2026-11-05T15:24Z
    Session: session_01L6bhgVwQZbHRRM9CaXeKif
    Account: os-sales
    Branch: claude/project-thread-5qt4jg (card thread of this project; a thread can push only its designated branch — measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-30327
    Domain: domain:ui
    Seat: domain:ui#5
    File surface: ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx (the New datasource dialog: schema-mode default and wording, the managed datasource's no-sync note, the SQLite Filename placeholder) + new studio namespace keys (en/zh) + their tests + one root .changeset/. ⛔ packages/**: if the driver form labels (Filename, Auto-migrate schema) come from the server's driver schema, the dev reports it and the seat files a domain:server card.
    Container & model: M, mode:thread, model: default, effort: high
    Clause-②: yes (expected: new studio keys; the dev declares the final arm)
    Metadata-protocol: none
    Responsibility: the New datasource dialog | the SQLite Filename box holds :memory: as a value, so typing a path appends to it | every administrator connecting a SQLite file
    Thread-read: 6652062778
    Premise: holds (on origin/main 8e5fabe5 the dialog still defaults to managed and holds :memory: as a value)
    Serial constraints cleared: PR #30493 (this seat, the same file) merged 2026-11-05T15:17Z; the branch starts from it. The server half landed in PR #30395 (merged). One PR carries this card's ui half and #30327, because both change the same dialog.

    Dispatch order lives in the card thread's opening message.

  9. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#5 · os-sales · session_01L6bhgVwQZbHRRM9CaXeKif

    Landed at 2026-11-05T16:43Z: PR #30561 merged as 0d54279e73 (seat ACCEPT 6663075162 on head fd64ec80, TIER_DEFAULT contract review PASS 6663047260), Fixes #30327 and Fixes #30331. The merge read 2026-11-05T16:41Z on the PR.

    probe reading
    git grep -c "NEW_DATASOURCE_SCHEMA_MODE|withBoxDefaults" origin/main -- ui/packages/app-shell/src/views/metadata-admin/datasource/DatasourceResourcePage.tsx 6 (a new datasource starts on External; a driver box's default is a placeholder, sent when left empty)
    card state closed (completed) by the merge

    State change: pm:dispatched removed. Server follow-ups from the card thread: #30562 (a managed SQL datasource drops and recreates an existing _id-without-id table, rows lost) and #30563 (driver form labels are English in every console language).

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions