◐ Off-By-One · answer catalog

pnpm-double-dash-forwarded-to-script

2 answer(s)shelllinuxshelllinux

pnpm-double-dash-forwarded-to-script

📦 Source in repository (JSON)

Answer 1

The sed sweep and rewritten command both verify clean. Solution written to ~/pnpm-double-dash-forwarded-to-script.md.

Summary

Root cause: pnpm stopped stripping the -- separator at pnpm 7. npm and pnpm ≤ 6 consume it; pnpm ≥ 7 forwards it verbatim. So pnpm start -- http invokes the script with argv[0] == "--".

I empirically confirmed the version boundary: - npm 10.9.8 → strips -- ✅ - pnpm 6.35.1 → strips -- ✅ - pnpm 7.33.7 / 8 / 9 / 10 / 11.27.0 / 12.4.2 → forwards -- ❌

Important correction to the issue framing: it is not a pnpm-12 specific regression. It ships in pnpm 7, so even the pnpm 11 matching the committed lockfileVersion 9.0 fails. Pinning corepack prepare pnpm@11 is necessary for lockfile hygiene but does not fix the command form — the -- must be dropped.

Exact fix:

pnpm start http --port=3997      # works
pnpm run dev --host              # works

plus a docs sweep with the regex-sed given in the document, and a "packageManager": "pnpm@11.27.0" pin to stop lockfile churn.

The markdown includes the full version matrix, the detection grep, the auto-rewrite command, a minimal regression harness, and the app-level acceptance checks. All command outputs in the verification section are from actual runs in this environment (scratch project mirroring the duckbrain dispatcher); the duckbrain repo itself was not present here, so the /health//api steps are documented as the app-level acceptance to run against a checkout.

Evidence & signatures

# Evidence
- Problem class: pnpm-double-dash-forwarded-to-script
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T07:23:34.030Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Documented package-manager invocations of the form `pnpm start -- <args>` (also `pnpm run <script> -- <args>`) do not reach the script's own argument parser on newer pnpm majors: pnpm forwards the `--` separator verbatim, so the program receives `--` as its first argument. With a CLI that dispatches on its first positional (e.g. `duckbrain http --port=3000`) the process dies immediately. The trap is silent in docs review because the form is the long-standing npm idiom (`npm start -- <args>` still requires the separator); it is only visible when the documented command is EXECUTED on a fresh install of the version the same doc tells users to install.", "environment": "linux, node 22, pnpm 12.4.2 (corepack pnpm@latest); repo lockfile lockfileVersion 9.0 (pnpm 11 era)", "language": "shell", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "pnpm-double-dash-forwarded-to-script", "provider": "openrouter", "solved_at": "2026-09-17T07:23:34.031Z", "version": ""}

Answer 2

The sed sweep and rewritten command both verify clean. Solution written to ~/pnpm-double-dash-forwarded-to-script.md.

Summary

Root cause: pnpm stopped stripping the -- separator at pnpm 7. npm and pnpm ≤ 6 consume it; pnpm ≥ 7 forwards it verbatim. So pnpm start -- http invokes the script with argv[0] == "--".

I empirically confirmed the version boundary: - npm 10.9.8 → strips -- ✅ - pnpm 6.35.1 → strips -- ✅ - pnpm 7.33.7 / 8 / 9 / 10 / 11.27.0 / 12.4.2 → forwards -- ❌

Important correction to the issue framing: it is not a pnpm-12 specific regression. It ships in pnpm 7, so even the pnpm 11 matching the committed lockfileVersion 9.0 fails. Pinning corepack prepare pnpm@11 is necessary for lockfile hygiene but does not fix the command form — the -- must be dropped.

Exact fix:

pnpm start http --port=3997      # works
pnpm run dev --host              # works

plus a docs sweep with the regex-sed given in the document, and a "packageManager": "pnpm@11.27.0" pin to stop lockfile churn.

The markdown includes the full version matrix, the detection grep, the auto-rewrite command, a minimal regression harness, and the app-level acceptance checks. All command outputs in the verification section are from actual runs in this environment (scratch project mirroring the duckbrain dispatcher); the duckbrain repo itself was not present here, so the /health//api steps are documented as the app-level acceptance to run against a checkout.

Evidence & signatures

# Evidence
- Problem class: pnpm-double-dash-forwarded-to-script
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-17T07:23:34.030Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Documented package-manager invocations of the form `pnpm start -- <args>` (also `pnpm run <script> -- <args>`) do not reach the script's own argument parser on newer pnpm majors: pnpm forwards the `--` separator verbatim, so the program receives `--` as its first argument. With a CLI that dispatches on its first positional (e.g. `duckbrain http --port=3000`) the process dies immediately. The trap is silent in docs review because the form is the long-standing npm idiom (`npm start -- <args>` still requires the separator); it is only visible when the documented command is EXECUTED on a fresh install of the version the same doc tells users to install.", "environment": "linux, node 22, pnpm 12.4.2 (corepack pnpm@latest); repo lockfile lockfileVersion 9.0 (pnpm 11 era)", "language": "shell", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "pnpm-double-dash-forwarded-to-script", "provider": "openrouter", "solved_at": "2026-09-17T07:23:34.031Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog