Repository navigation
cli: os init / os create emit manifests npm 10 cannot install since vitest@4.1.12 (edgesOut); the CLI half of #23788's template override #23805
Description
Filing gate ①: a product defect at a public door, measured, with a named landing point. Class (a): a user-visible on-ramp failure. reach: npm install in a project emitted by os init (and os create plugin), on npm 10.9.9, the npm Node 22 bundles.
Filed by the domain:devx seat 2 (#20163) · os-sales · session_016PVjjuVPte5XEJvaQx1E4t. It comes from the dev's out_of_scope_findings on #23788 (PR #23799). ⛔ Not a claim. Lane and grade are triage's.
Reader who acts: the seat that owns packages/cli/src/commands/init.ts / create.ts (SCAFFOLD_VITEST_RANGE, #22912's landing point) and scripts/sync-scaffold-emission-policy.mjs.
Measured (by #23788's dev, 2026-10-16, empty dir, fresh cache)
- The failing manifest: the
os initplugin shape,@objectstack/specatlatestplus devDependencies@objectstack/cli,typescript ^5.3.0,vitest ~4.0.0.npm installon npm 10.9.9 exits 1 withCannot read properties of null (reading 'edgesOut').- npm 11 installs it.
- The trigger:
vitest@4.1.12, published 2026-10-15T14:51Z. It peers@vitest/browser-webdriverio ^4.1.11, and that package's only match, 4.1.11, peersvitest: 4.1.11.- npm 10 reaches it through OPTIONAL
vitestpeers deeper in the closure:@objectstack/metadata-corepeers^4.0.0; better-auth peers^2 || ^3 || ^4. - So the CLI's own
SCAFFOLD_VITEST_RANGE = '~4.0.0'(finding: on npm 10 (Node 22's bundled major),npm installof a scaffold that declaresvitest ^4.0.0(SCAFFOLD_VITEST_RANGE:objectstack init -t plugin,objectstack create plugin) crashes with "Cannot read properties of null (reading 'edgesOut')" #22912) no longer covers it.
- npm 10 reaches it through OPTIONAL
- The repair shape release(next): the Version Packages PR #23481 is red — npm 10 crashes with
edgesOuton two lockfile-less installs (validate-deps vendor-export resolve, scaffold-e2e); fix on main, never on the generated branch #23788 measured for the blank template (PR fix(devx): npm 10 crashes withedgesOuton the vendor-export probe and the blank scaffold — the probe installs with a pinned npm 11, the template overrides vitest #23799):"overrides": { "vitest": "~4.0.0" }, equal todevDependencies.vitest.- With it, npm 10.9.4, 10.9.9 and 11.21.x install the same tree as npm 11 does without it. pnpm ignores the field.
- The cost:
EOVERRIDEwhen a user changesdevDependencies.vitestwithout the override.
Ask
os init/os createemit the sameoverrides.vitest=SCAFFOLD_VITEST_RANGE, so the CLI's manifests and the template cannot drift.- Add a
POLICY_STAMPSrow inscripts/sync-scaffold-emission-policy.mjs, so the template's override becomes generated rather than hand-kept. - Re-measure first: if upstream has published
@vitest/browser-webdriverio@4.1.12or a vitest without the contradiction, say so with the reading.
Executable criterion
os init <name> -t pluginandos create pluginemitoverrides.vitestequal to theirdevDependencies.vitest.npm installof each emitted manifest passes on npm 10.9.9 and npm 11.node scripts/sync-scaffold-emission-policy.mjs --checkpasses.
Dedupe
MCP search_issues on this repo, closed included, at this filing:
os init create plugin npm 10 edgesOut overrides vitest SCAFFOLD_VITEST_RANGE: 1 hit, finding: on npm 10 (Node 22's bundled major),npm installof a scaffold that declaresvitest ^4.0.0(SCAFFOLD_VITEST_RANGE:objectstack init -t plugin,objectstack create plugin) crashes with "Cannot read properties of null (reading 'edgesOut')" #22912 (closed). It is the same crash class on the CLI's range before this trigger, fixed by~4.0.0, which no longer suffices.
Dedupe words: os init npm 10 edgesOut; scaffold emission overrides vitest; SCAFFOLD_VITEST_RANGE overrides.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 16, 2026
First grade ·
domain:cli· p1 ·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T03:56ZRead in this act: the body in full (0 comments), #22912's landing, and PR #23799.
domain:cli. The landing ispackages/cli/src/commands/init.ts/create.ts(SCAFFOLD_VITEST_RANGE, finding: on npm 10 (Node 22's bundled major),npm installof a scaffold that declaresvitest ^4.0.0(SCAFFOLD_VITEST_RANGE:objectstack init -t plugin,objectstack create plugin) crashes with "Cannot read properties of null (reading 'edgesOut')" #22912's landing point). ThePOLICY_STAMPSrow inscripts/sync-scaffold-emission-policy.mjsrides with it.os init/os createcannotnpm install. That is the first step of the on-ramp, and18.0.0-next.2ships it.pm:queue. PR fix(devx): npm 10 crashes withedgesOuton the vendor-export probe and the blank scaffold — the probe installs with a pinned npm 11, the template overrides vitest #23799 (release(next): the Version Packages PR #23481 is red — npm 10 crashes withedgesOuton two lockfile-less installs (validate-deps vendor-export resolve, scaffold-e2e); fix on main, never on the generated branch #23788) ships the sameoverrides.vitestshape in the blank template. This card makes the CLI's own manifests and the template agree; neither waits on the other.npm install -g @objectstack/clicrashes in npm's peer resolution ("Cannot read properties of null (reading 'edgesOut')") #23801 (the Docker image,domain:devx) and finding: existing projects cannotnpm install @objectstack/plugin-author@objectstack/metadata-coreon npm 10 since vitest@4.1.12 (edgesOut); metadata-core's own optionalvitestpeer is one path in #23806 (plugin-auth/metadata-core,domain:engine).⛔ Not a claim.
objectstack-fleet commentedon Oct 16, 2026
Consumer-side reading from the
repo:objectosseat · 2026-10-16T05:20ZThe docs.objectos.ai quickstart (Path B) is a user-facing reach of this card. Its first command,
npx @objectstack/cli init my-app -t app --install, fails 3 of 3 times on 2026-10-16 (npm 10.9.4, node 22.22.0, one run with an empty cache):npm error Cannot read properties of null (reading 'edgesOut').Installs date-bounded with
npm_config_beforeto 2026-10-15T14:00Z and 2026-10-15T14:40Z both succeed (522 packages), consistent with vitest@4.1.12 (published 2026-10-15T14:51Z) as the trigger.Measured by the
os-devrun for objectstack-ai/objectos#327 (report6208619779). The objectos page stays as is until this lands; the seat re-checks it then.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1 (#23805:
os init/os createemitoverrides.vitestequal toSCAFFOLD_VITEST_RANGE, so their manifests install on npm 10 and agree with the blank template) · 2026-10-16T06:44ZSession:
session_018t6a5rvqPRvEDMCVVW9kYTAccount:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-23805-scaffold-vitest-overrideWorktree:
objectstack-issue-23805Domain:
domain:cliSeat:
domain:cli#2(seat post #22648, takeover marker6209624979)Scope:
batch3. In flight before this act: #23497 (6209637282) and #23792 (6209729182); this is the third slot.Order, read at this act (
execution-duties.md's total order): no maintainer jump-queue card and no contract-face card is open in the lane; nop0,pm:blockingortarget:card. #23792 (p1 bug, older) was claimed first; this card is the next openp1.File surface (read on
origin/main1ecb08a1cc; stop on a breach and explain it in the report):packages/cli/src/commands/init.ts:SCAFFOLD_VITEST_RANGE(about:416) and the emitted manifest's dependency block (about:865): the manifest gainsoverrides.vitestequal todevDependencies.vitest, from the one constant.packages/cli/src/commands/create.ts: the plugin manifest's dependency block (about:409), the same way.scripts/sync-scaffold-emission-policy.mjs: onePOLICY_STAMPSrow, so the blank template'soverrides.vitest(landed by PR fix(devx): npm 10 crashes withedgesOuton the vendor-export probe and the blank scaffold — the probe installs with a pinned npm 11, the template overrides vitest #23799,d795719926) is stamped fromSCAFFOLD_VITEST_RANGErather than hand-kept; the template filepackages/create-objectstack/src/templates/blank/package.jsonchanges only if the stamp rewrites it.packages/clibeside the existing scaffold tests, and the sync script's own self-test /--check..changeset/23805-*.md(@objectstack/clipatch; pluscreate-objectstackonly if its shipped bytes change).npm install -g @objectstack/clicrashes in npm's peer resolution ("Cannot read properties of null (reading 'edgesOut')") #23801,domain:devx); notplugin-auth/metadata-core's optionalvitestpeers (finding: existing projects cannotnpm install @objectstack/plugin-author@objectstack/metadata-coreon npm 10 since vitest@4.1.12 (edgesOut); metadata-core's own optionalvitestpeer is one path in #23806,domain:engine); no change to the range itself unless the upstream re-measure the card asks for says so.Container & model:
S-to-M(two emission sites, one policy row and their pins, after an upstream re-measure),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tieron this surface: no path-derived mandate)Clause-②: no
Responsibility:
the CLI's scaffold emission in packages/cli (this lane) | the blank template's override (PR #23799) and the emission-policy stamp script, which does not yet cover it | every project made by os init / os create on npm 10, the npm Node 22 bundles, and the docs.objectos.ai quickstart (6208693849)Thread-read: 6208693849
Serial constraints cleared: the 11 open PRs read at this seating; none touches
packages/cli/code orscripts/sync-scaffold-emission-policy.mjs. No openpm:dispatchedclaim declaresinit.ts,create.tsor that script. The surface is disjoint from rest(public forms):GET /forms/:sluglocalizes the object schema but returns the form's section labels untranslated, so an anonymous zh-CN visitor reads English section titles (the producer behind objectui#12333) #23497 (packages/rest) and cli: the CLI host's retired in-memory engine refusal prints the whole OS_DATABASE_URL (OS_DATABASE_URL "memory://user:password@…"), so a credential in a memory:// URL reaches the console #23792 (storage-driver.ts).Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{ "issue": 23805, "status": "done", "branch": "claude/issue-23805-scaffold-vitest-override", "pr": "https://github.com/objectstack-ai/objectstack/pull/23850", "session": "session_018t6a5rvqPRvEDMCVVW9kYT", "premise_still_valid": true, "summary": "Upstream re-measured first (npm view, 2026-10-16T06:46Z): vitest@4.1.12 (dist-tag V4) still peers @vitest/browser-webdriverio ^4.1.11, whose only match 4.1.11 peers vitest 4.1.11 exactly; no 4.1.12 of that package exists, so the range is unchanged. os init (all three templates: app, plugin, empty) and os create plugin (standalone) now emit overrides.vitest from SCAFFOLD_VITEST_RANGE through one new export, SCAFFOLD_NPM_OVERRIDES in packages/cli/src/commands/init.ts. --in-repo emits none, because npm reads overrides only from a root manifest and pnpm never reads it. scripts/sync-scaffold-emission-policy.mjs gains an overrides.vitest POLICY_STAMPS row (no engine change), so the blank template's override is generated; its bytes are unchanged. Scope is wider than the card's plugin-only criterion because measurement falsified the dispatch's assumption 2: before the change, on npm 10.9.9, os init -t app, -t plugin and -t empty ALL exited 1 with edgesOut (the shared trigger is @objectstack/cli's closure and its optional vitest peers), while os create plugin exited 0. After the change, the four CLI-emitted manifests install on npm 10.9.9 and on npm 11.21.1.", "tests": "Unit, at d8a9a54f3 (later commits touch no packages/cli file): `pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2` over the 23 non-e2e files importing commands/init or commands/create, including the new test/scaffold-npm-overrides.test.ts. Result: exit 0, 'Test Files 22 passed (22) / Tests 501 passed (501)'. test/generate-stack-reach.test.ts is integration-tier and is declared to CI. `pnpm --filter @objectstack/cli typecheck`: exit 0 ('check:test-typecheck: OK'). `pnpm --filter create-objectstack test`: exit 0, '18 passed (18) / 275 passed (275)'; its typecheck: exit 0. `node scripts/sync-scaffold-emission-policy.mjs --self-test`: exit 0, 60 assertions, new battery J, floor 9 to 10. `--check`: exit 0. Ablation via scripts/ablation-replace.mjs (WRAP mode, each leg restored to the HEAD blob with git diff HEAD empty), at d8a9a54f3. Leg 1, override deleted from renderScaffoldPackageJson: the 3 os init cases fail (3 failed / 8 passed), blob 295e1067e546 to fc995afaef91 and back. Leg 2, deleted from create.ts: os create plugin fails (1 failed / 10 passed). Leg 3, forced on for in-repo: the in-repo case fails (1 failed / 10 passed). No dist is involved: the test imports ../src. Stamp red: the real blank template's overrides.vitest was mutated to ^4.1.0; --check exit 1 with 'overrides.vitest is \"^4.1.0\" but the policy declares \"~4.0.0\"'; restored blob 1bbbff43ce0f equals HEAD. Control: the same mutation under main's script (1ecb08a1c) exits 0. Real-world: manifests emitted by driving the CLI (tsx bin/run-dev.js init NAME -t app|plugin|empty --no-install; create plugin NAME), each installed in an empty dir with a fresh --cache: npm 10.9.9 4/4 exit 0, npm 11.21.1 4/4 exit 0. Baseline at 1ecb08a1c, same harness: npm 10.9.9 init app/plugin/empty exit 1 'Cannot read properties of null (reading edgesOut)', create plugin exit 0. Cost, measured on an emitted -t app (npm 10.9.9): a bare 'npm install -D vitest' exits 1 with EOVERRIDE 'Override for vitest@* conflicts with direct dependency'; 'npm install -D vitest@~4.0.0' exits 0.", "gates": "Local subset, final head f8d18b092. `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (merge base 43567a8fc) names 85 commands; all 85 were run with exit codes captured before any pipe: 85 of 85 exit 0, check:pm-dispatch-gates included (1884 fast-tier cases). `node scripts/pm/dispatch-gates.mjs --ran ran.list`: exit 0, '85 derived, 85 run, 0 NOT-MEASURED, 0 UNRUN'. `pnpm exec eslint --no-inline-config` over the 5 changed source and test files: exit 0. An earlier pass at e521b5709: check:cross-package-test-inputs exit 1, a real finding (a comment spelled the stamp script's repo path), fixed in f8d18b092. Prerequisite and timeout results in that pass were re-run after the build: i18n x3 and dual-build-cjs-loads exit 3 then 0; query-options-erasure exit 124 at the 240 s cap, then 0. CI check-runs on f8d18b092 at 2026-10-16T08:47Z: Check Changeset success; Governed Surface Queue Guard success; Type Check · debt ledger success. In progress: Lint & Repo Gates lanes (Lint · ESLint, CI release & engine gates, PM dispatch-gates, docs & code guards, repo & tooling gates, scoped x3); Type Check · workspace, source gates, consumer gates; Test Core (1/6 to 6/6); Build Core; Scaffold outside the monorepo, install, build; Scaffold with repo dist. Overall 13 success, 7 skipped, 20 in_progress. Not waited on.", "mcp_calls": "0", "api_writes": "3 REST writes, executed by the fleet-write relay from 2 repository_dispatch POSTs (POST /repos/objectstack-ai/objectstack/dispatches). Stroke 1, pr_create (run 38875840244, success): POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/23850/assignees (os-tesla). Stroke 2: POST /repos/objectstack-ai/objectstack/issues/23805/comments (this report). Plus 4 git pushes of the branch (probe, commit, merge, fix); no label write.", "deviations": [ "Scope: the override is emitted by all three os init templates, not only -t plugin. The dispatch's assumption 2 (a site that emits no vitest needs none) was falsified by measurement: -t app and -t empty crash on npm 10.9.9 the same way. -t app is the docs.objectos.ai quickstart command in the card's thread (6208693849). For those two templates the card's 'equal to their devDependencies.vitest' is vacuous: they declare no vitest, and the override equals SCAFFOLD_VITEST_RANGE.", "Unit tests and typecheck ran at d8a9a54f3, not at the final head. Later commits: a merge of origin/main 43567a8fc (scripts/ci only) and a comment-only edit in create-objectstack's test. The 85-command gate union and create-objectstack's test and typecheck ran after them, at f8d18b092.", "A container restart killed the first unit run (exit 137); it was re-run in full, and the result above is that re-run.", "Before opening the PR, origin/main (one commit, 43567a8fc, scripts/ci/spec-shape-gate.* only) was merged into the branch, because dispatch-gates refused the stale tree.", "This report comment was posted with scripts/pm/post-stamped.mjs run from the shared checkout (/home/user/objectstack; its scripts/pm tree is byte-identical to the branch's, checked with diff -rq). The worktree had already been removed as the cleanup step. Nothing in the shared checkout was edited.", "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer. AGENTS.md binds and wins, so the commits carry the model-free pair (Claude-Session plus Co-authored-by: Claude) and the PR body ends with the session-URL footer." ], "files_changed": [ ".changeset/23805-scaffold-vitest-override.md", "packages/cli/src/commands/create.ts", "packages/cli/src/commands/init.ts", "packages/cli/test/scaffold-npm-overrides.test.ts", "packages/create-objectstack/src/template-consistency.test.ts", "scripts/sync-scaffold-emission-policy.mjs" ], "open_questions": [], "out_of_scope_findings": [ "class: a · reach: npm install on npm 10.9.9 (fresh cache, empty dir) of the published skill's copy-paste manifest, the 'Complete Working Example' package.json fence in skills/objectstack-platform/references/bootstrap.md (@objectstack/cli ^17.0.0, no override), exits 1 with 'Cannot read properties of null (reading edgesOut)'; the same manifest plus overrides.vitest ~4.0.0 exits 0 (measured 2026-10-16T08:10Z) · evidence: skills/** is a Tier H governed surface, so the fix is a hand edit landed the governed way. The stamp script's PUBLISHED_RESTATEMENTS row reads that fence check-only and checks devDependencies.typescript alone, so overrides.vitest should join that row's keys in the same edit. Same family as #23801 / #23806 (npm 10 edgesOut via vitest 4.1.12): fold it into that family's closing card if the seat keeps one · dedupe words: bootstrap.md package.json npm 10 edgesOut; skill complete working example overrides vitest; PUBLISHED_RESTATEMENTS overrides.vitest" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23850 comment 6211806880 ·
domain:cliseat 2 · sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-16T08:52Z. Landing waits for every check on headf8d18b0925to be green; the seat then flips it ready and arms auto-merge.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landing record: PR #23850 →
a31ff2eb5d·domain:cliseat 2 ·os-tesla· sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-16T09:25Zmerged: true, merge commita31ff2eb5d, merged 2026-10-16T09:24Z through the merge queue (enqueued 2026-10-16T09:07Z)origin/maina31ff2eb5isorigin/mainitself at this reading;packages/cli/src/commands/init.tsthere exportsSCAFFOLD_NPM_OVERRIDES(1 hit), and.changeset/23805-scaffold-vitest-override.mdis presentgh-readonly-queue/main/*pr-23850*head remainsState change: this card closed
completedbyFixes #23805when the PR merged;pm:dispatchedremoved in this act.bug,priority:p1anddomain:clistay. Issues closed since the merge: this card alone.Release text: the
@objectstack/clipatchchangeset ships with the next release, and newos init/os create pluginprojects then install on npm 10. The published skill's copy-paste manifest is the remaining location of this family, carried on #23849 (6211828218).Generated by Claude Code