What went red
Merge-queue build 32708418190,
Test Core (5/6), on PR #11609 (a test-only diff in packages/cli that cannot reach
packages/create-objectstack):
FAIL src/scaffold-next-steps-pm.test.ts
> scaffolder "Next steps" names the package manager it actually detected (#10322)
> with pnpm on PATH: prints pnpm consistently, never bare npm
AssertionError: expected '\n cd my-app\n npm install\n …' to match /\bpnpm run dev\b/
Why it is not a real regression, and why that is the problem
The scaffolder decides what to print with a probe that swallows every failure mode into one answer
(packages/create-objectstack/src/index.ts:125):
functiondetectPackageManager(): string{try{execSync('pnpm --version',{stdio: 'ignore'});return'pnpm';}catch{return'npm';}}npm install in the output therefore means the probe threw, not the code chose npm. The two are
not distinguishable from the assertion message.
The test's own vacuity guard — expect(() => which('pnpm')).not.toThrow() — does not cover the
probe, because the two run in different working directories:
| cwd | what resolves |
|---|
the test's sanity command -v pnpm | the package dir, inside the repo | the pinned packageManager, pnpm@10.31.0 |
the scaffold child's pnpm --version | mkdtemp under os.tmpdir(), outside the repo | Corepack's own default |
Measured locally on one machine, one binary, two cwds:
$ (cd <repo root> && pnpm --version) → 10.31.0
$ (cd /tmp && pnpm --version) → 10.33.0
The queue job runs pnpm through Corepack — COREPACK_HOME: /home/runner/work/_temp/corepack is in
that job's env, and a "Restore the Corepack store" cache step is part of it. os.tmpdir() on a GitHub
runner is /home/runner/work/_temp, which has no package.json above it, so the outer leg is the one
that has to resolve (and potentially fetch) a version the repo never pinned. Nothing in the assertion
distinguishes "the scaffolder regressed" from "that resolution failed once".
Related but distinct: #11369 is about Corepack downloads in workflow jobs. This is a Corepack
resolution inside a test's child process, and would survive that card being fixed.
Suggested shape (not a ruling — for triage)
The pin is worth keeping; what needs removing is the dependency on an unpinned resolution:
- Make the probe's outcome the fixture rather than the ambient environment — run the pnpm leg under
a controlled PATH holding a stub pnpm that exits 0, the exact mirror of the npm-fallback leg's
existing makePnpmlessBin(). Both branches then become hermetic, and the test stops asserting a
property of the runner. - Independently: consider whether
detectPackageManager() collapsing spawn failure and pnpm
absent into one answer is itself worth separating, since a user with pnpm installed but a slow or
failing probe is told to run npm. That is a user-facing question, not a test one — split it out if
triage agrees it is a card.
Filed unassigned, for grading. Not folded into #11609: different package, and that PR's card
(#11301) is a packages/cli exit-code pin.
What went red
Merge-queue build 32708418190,
Test Core (5/6), on PR #11609 (a test-only diff inpackages/clithat cannot reachpackages/create-objectstack):Why it is not a real regression, and why that is the problem
The scaffolder decides what to print with a probe that swallows every failure mode into one answer
(
packages/create-objectstack/src/index.ts:125):npm installin the output therefore means the probe threw, not the code chose npm. The two arenot distinguishable from the assertion message.
The test's own vacuity guard —
expect(() => which('pnpm')).not.toThrow()— does not cover theprobe, because the two run in different working directories:
command -v pnpmpackageManager,pnpm@10.31.0pnpm --versionmkdtempunderos.tmpdir(), outside the repoMeasured locally on one machine, one binary, two cwds:
The queue job runs pnpm through Corepack —
COREPACK_HOME: /home/runner/work/_temp/corepackis inthat job's env, and a "Restore the Corepack store" cache step is part of it.
os.tmpdir()on a GitHubrunner is
/home/runner/work/_temp, which has nopackage.jsonabove it, so the outer leg is the onethat has to resolve (and potentially fetch) a version the repo never pinned. Nothing in the assertion
distinguishes "the scaffolder regressed" from "that resolution failed once".
Related but distinct: #11369 is about Corepack downloads in workflow jobs. This is a Corepack
resolution inside a test's child process, and would survive that card being fixed.
Suggested shape (not a ruling — for triage)
The pin is worth keeping; what needs removing is the dependency on an unpinned resolution:
a controlled
PATHholding a stubpnpmthat exits 0, the exact mirror of the npm-fallback leg'sexisting
makePnpmlessBin(). Both branches then become hermetic, and the test stops asserting aproperty of the runner.
detectPackageManager()collapsing spawn failure and pnpmabsent into one answer is itself worth separating, since a user with pnpm installed but a slow or
failing probe is told to run npm. That is a user-facing question, not a test one — split it out if
triage agrees it is a card.
Filed unassigned, for grading. Not folded into #11609: different package, and that PR's card
(#11301) is a
packages/cliexit-code pin.