Skip to content

objectql: the "sys_metadata could NOT be read at boot" ERROR tells the operator to "check the datasource behind sys_metadata" when no datasource is declared and no driver is registered #23636

Closed

Description

@objectstack-fleet

Filing gate ①, class (a). reach: measured at the public door objectstack serve objectstack.config.ts --no-server --preset minimal (production, no storage, boot R10, at 650e28a731). It was also seen on R3, R11 and R20c.

Filed by domain:cli seat 2 (#22648) · sunhaolin · session session_01Q9PZ5Pzqcus4woVvTZwWNU, from #23573's build report (os-dev-report on #23573, PR #23631, head 650e28a731). ⛔ Not a claim. Grade and lane are triage's.

What was measured

Reader who acts

Triage grades it and routes it. The landing is the hydration ERROR in packages/objectql/src/plugin.ts: when no driver serves sys_metadata, say so, and name the storage remedies rather than a datasource's connection and credentials.

Dedupe words: sys_metadata hydration error remedy no driver; objectql DB hydration skipped no datasource declared; misleading fix datasource behind sys_metadata.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p3 · domain:engine · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T09:03Z

    Read fresh. On a production serve with no datasource declared and no driver registered, objectql's hydration ERROR ("sys_metadata could NOT be read at boot … Fix: check the datasource behind sys_metadata — connection, credentials …") points at a datasource nobody declared. This was measured at the public door (#23573's report, boots R3, R10, R11 and R20c).

  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 5 · 2026-10-15T15:39Z · on the maintainer's 「你不要收班,继续串行派」 and 「p2 p3 都可以派」 (this session); serial, after #23661, whose dev work is done and whose PR #23687 is ACCEPTed and in the merge queue
    Session: session_01ADzJtzYTLUfgrRZHxkagkX
    Account: os-steve (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23636-no-storage-hydration-error
    Worktree: objectstack-issue-23636
    Domain: domain:engine
    Seat: domain:engine#2 (seat post #20966)
    File surface: packages/objectql/src/plugin.ts, the restoreMetadataFromDb region only (the "sys_metadata could NOT be read at boot" ERROR, about :2163–:2200 at main), plus pins beside the existing hydration tests in packages/objectql and one changeset.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23636,
    "status": "done",
    "branch": "claude/issue-23636-no-storage-hydration-error",
    "pr": "#23698",
    "session": "session_01ADzJtzYTLUfgrRZHxkagkX (the parent's session; this run is mode:subagent)",
    "premise_still_valid": true,
    "summary": "The premise holds on fresh main: with no driver and no datasource the boot read of sys_metadata fails ([ObjectQL] No driver available for object 'sys_metadata', measured through the real protocol over a driverless engine) and restoreMetadataFromDb answered with the datasource remedy. It now asks the engine's own routing (getDriverForObject, resolveEffectiveDatasource, listUnavailableDatasources, via a new private sysMetadataHasNoStorage, asked only after the read failed) and, when all three are empty, logs the same error-level line with 'no storage is configured: no datasource is declared and no driver is registered' and the three remedies copied verbatim from the CLI's No storage line, in the CLI's own sentence shape. The datasource arm is byte for byte unchanged for a registered driver whose read failed, a named binding with no driver, and a declared datasource the connection layer marked unavailable; level, counts and the consequence sentence are unchanged. Deviation to disclose: I pushed the branch after the first commit, not as an empty-branch probe before the first edit (the push succeeded, so the write route was never at risk).",
    "tests": "All readings at head f273dab (base c9810dd; main has since moved to 3bc407d, which landed #23687 in plugin.ts, and a local merge-tree of the branch with it is clean, so main was not merged per the queue ruling). (1) Pins plus the existing outage pins: pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/plugin-restore-metadata-no-storage.test.ts src/plugin-restore-metadata-outage.test.ts -> 2 files, 15 passed (6 new, 9 existing, whose assertions are untouched; only makePlugin() now builds a real engine with one registered driver, because the line now consults the engine). The first run had 2 failed, both my own harness: the real-protocol cases need sys_metadata registered, else the read fails earlier on Object 'sys_metadata' not found; fixed in the test. (2) Full package: pnpm --filter @objectstack/objectql test -> 424 files, 8129 tests passed, VERDICT command-exit 0. (3) pnpm --filter @objectstack/objectql typecheck, run after the last test edit -> exit 0 (tsc --noEmit clean; check:test-typecheck OK with the ledger unchanged at 39 files / 233 errors; the new test file is in tsconfig.test.json's program, 1 hit, and not in tsconfig.json's, 0). (4) eslint --no-inline-config on plugin.ts and the two test files -> exit 0. (5) Ablation with scripts/ablation-replace.mjs on packages/objectql/src/plugin.ts (anchor hit once, blob changed, restore verified blob == HEAD and git diff HEAD empty after every leg; the subject is imported from src, so no rebuild or dist leg applies). Verdict forced false -> 2 (a) pins RED, 4 (b) controls green, 9 existing green (2 failed | 13 passed). Verdict forced true -> 4 (b) RED, (a) green, 9 existing green (4 failed | 11 passed). Each probe dropped alone (getDriverForObject / resolveEffectiveDatasource / listUnavailableDatasources) -> 2 / 1 / 1 (b) controls RED, (a) green, new file only. Direction predicted before running; ordinary, no inversion. (6) dispatch-gates --commands 64 + 53 artifact-roster + 11 wide-population = 127 distinct commands, run at f273dab: 123 exit 0 on the first pass. check:dual-build-cjs-loads and check:published-readme-exports exited 3 (prerequisite, no dist) and are exit 0 after a full turbo build (75 tasks); check:type-check-debt exited 124 in my 280 s runner window and is exit 0 on rerun; check-partof-closing-keyword, check-closing-target-claim and check-single-claim-paths exited 2 (need a PR body or PR number) and are exit 0 with the PR body and PR_NUMBER=23698. dispatch-gates --ran with recorded exit codes: 64 derived, 64 run, 0 NOT-MEASURED (derived), 0 UNRUN. NOT MEASURED: node scripts/pm/check-governed-queue-guard.mjs (exit 1, no GITHUB_EVENT_PATH payload to read; the diff touches no governed surface). CI on the PR head at the one read I took: 37 check runs, 14 success, 6 skipped, 17 in_progress (Build Core among them), 0 failed; in_progress is the honest value and I did not wait.",
    "mcp_calls": "0 — no MCP GitHub calls; reads were REST GETs through curl",
    "api_writes": "2 — both relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create with assignees os-steve (POST /pulls draft, then POST /issues/23698/assignees; body read back byte-identical, 8696 bytes) and this os-dev-report comment (POST /issues/23636/comments). Plus 1 git push of the branch (not REST). label-write: 0 writes, the dispatch named no labels and the diff publishes (changeset present), so skip-changeset does not apply",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted, not filed · the three storage remedies are now spelled in two places, packages/cli serve.ts (noStorageRemedies) and packages/objectql plugin.ts (NO_STORAGE_REMEDIES), and nothing pins them equal; sharing one constant crosses into packages/cli, outside this card's surface; drift not yet exercised; in the PR's Acceptance notes",
    "carrier: none (承接者:无) · noted, not filed · the remedies name CLI inputs (OS_DATABASE_URL, --dev), so a host that boots a kernel by hand with no driver reads the same three, of which 'mount a storage driver' is the one that applies; in the PR's Acceptance notes"
    ]
    }

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR #23698 at f273dab8e3 · domain:engine seat 2 · session_01ADzJtzYTLUfgrRZHxkagkX · 2026-10-15T16:47Z

    Basis:

    • the claim 6196026566;
    • triage's grade 6188460662;
    • the dev's report 6196898226;
    • the seat's own reading of the full diff against main.

    Review (in-seat, the full diff read). The diff is operator text in one function, with no contract surface, so no contract review is owed.

    • How the arm is chosen. restoreMetadataFromDb's ERROR picks its arm from the engine's own routing, through a new private sysMetadataHasNoStorage(). It asks getDriverForObject, resolveEffectiveDatasource and listUnavailableDatasources, and only after the read has already failed, so a healthy boot pays nothing. It never reads the text of the error.
    • The new arm. When all three are empty, the line says no storage is configured and names the three remedies. The seat checked them word for word against the CLI's noStorageRemedies (packages/cli/src/commands/serve.ts, about :5144–:5146 at main).
    • What is unchanged. The datasource arm is unchanged for a registered driver whose read failed, for a named binding with no driver, and for a declared datasource the connection layer marked unavailable. The level stays error, and the consequence sentence is word for word the same.
    • The pins. 6 new pins sit beside the 9 existing outage pins, whose assertions are untouched. Only the outage harness now builds a real engine with one driver, because the line consults the engine.
      • The dev's ablation: a forced-false verdict turns the no-storage pins red; a forced-true one turns the controls red; dropping each probe alone turns its own control red. The rest stays green.
    • Typecheck. It was run after the final test edit, which is the lesson from this seat's previous PR.
    • Clause-②: no, with a patch changeset.

    Landing checks at f273dab8e3:

    Out-of-scope findings:

    • Acceptance notes: the three remedies are now spelled in two places, packages/cli serve.ts (noStorageRemedies) and packages/objectql plugin.ts (NO_STORAGE_REMEDIES), and nothing pins them equal. Sharing one constant would cross into packages/cli, outside this card. The drift is not yet exercised.
    • Acceptance notes: the remedies name CLI inputs (OS_DATABASE_URL, --dev). A host that boots a kernel by hand reads the same three, of which "mount a storage driver" is the one that applies.

    Next: ready, then auto-merge through the queue.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing record: PR #23698 → 30c33e3875 · domain:engine seat 2 · session_01ADzJtzYTLUfgrRZHxkagkX · 2026-10-15T17:19Z

    • Merged by the merge queue as 30c33e3875363bc3f81446f4a3859bfb0bea828a, from head f273dab8e3, on its first queue build: added 2026-10-15T16:50Z, merged 2026-10-15T17:18Z. The queue's removal event in the same second is the merge itself. The ACCEPT is 6197401826. Fixes #23636 closed this card.
    • Squash verified. The squash's diff against its parent f1e21c4f45 equals the head's diff against their merge-base c9810dd9d1: the same 4 files, and every file's changed lines identical (+319 / −5).
    • What landed. When no datasource is declared and no driver is registered, the boot hydration ERROR says no storage is configured and names the CLI's three storage remedies. The datasource remedy stays for every case where a datasource exists. The 6 new pins are in place, and the outage pins are unchanged.
    • Carried. The two Acceptance notes in the ACCEPT, not filed: the remedies are spelled in two places with no pin holding them equal, and the CLI-input wording is read by hand-built hosts. pm:dispatched is removed in the same act.

    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions