Skip to content

Vendored scan from a pnpm 11/12 workspace member with its own lock writes the override into a nested member pnpm-workspace.yaml that pnpm ignores, so the root frozen install fails and a plain pnpm install silently reinstalls the unpatched package #881

Description

[agent] Found by the scheduled pnpm bug-hunt routine (ledger #303).

Summary

This is the vendored twin of #880. In a pnpm workspace with sharedWorkspaceLockfile: false, a member has its own pnpm-lock.yaml, so scan --mode vendored run from the member goes ahead. It wires the member's lock and writes the file:.socket/vendor/… override in two places:

  • packages/a/package.json pnpm.overrides, which pnpm 11+ ignores;
  • a new nested packages/a/pnpm-workspace.yaml (packages: ['.'] + overrides:), which pnpm ignores because packages/a is a project of the root workspace. pnpm reads settings only from the root pnpm-workspace.yaml.

So on pnpm 11 / 12, the override the lock records isn't in any config pnpm reads from the root:

  • pnpm install --frozen-lockfile from the root exits 1 with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH (pnpm also warns "The settings in packages/a/pnpm-workspace.yaml do not apply").
  • A plain pnpm install from the root exits 0. It re-resolves packages/a/pnpm-lock.yaml, drops every .socket/vendor reference, and installs the upstream left-pad. That's a silent unpatch.

The scan itself exits 0 with status: success, applied: 1.

Impact

On pnpm 11/12, this workspace layout gets no protection from vendored mode. CI (frozen) breaks. The everyday pnpm install a developer runs silently reverts the lock to the vulnerable upstream package with exit 0, and the commit that follows loses the patch.

Repro (Linux, Node 22, pnpm 12.8.1)

A local mock of the patch API grants a vendored left-pad@1.3.0 tarball (batch / by-package / view / patches/package routes, as in crates/socket-patch-cli/tests/e2e_redirect_pnpm_build.rs).

mkdir -p ws/packages/a && cd ws
echo '{"name":"root","private":true}' > package.json
printf "packages:\n  - 'packages/*'\nsharedWorkspaceLockfile: false\n" > pnpm-workspace.yaml
echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"1.3.0"}}' > packages/a/package.json
pnpm install                                     # packages/a/pnpm-lock.yaml
(cd packages/a && socket-patch scan --mode vendored --json --yes --api-url $MOCK --org test-org --api-token fake)
#   exit 0, status success, applied 1
cat packages/a/pnpm-workspace.yaml               # NEW: packages: ['.'] + overrides: left-pad@1.3.0: file:.socket/vendor/…
rm -rf node_modules packages/a/node_modules
pnpm install --frozen-lockfile --store-dir "$(mktemp -d)"
#   WARN The settings in packages/a/pnpm-workspace.yaml do not apply …
#   ERR_PNPM_LOCKFILE_CONFIG_MISMATCH, exit 1
pnpm install --store-dir "$(mktemp -d)"
#   exit 0; packages/a/pnpm-lock.yaml now has 0 `.socket/vendor` references; left-pad/index.js is the upstream file

Expected vs actual

  • Expected: docs/ecosystems.md and CLI_CONTRACT.md describe vendored pnpm as wiring the override where pnpm reads it (pnpm-workspace.yaml overrides: on pnpm >= 10.5 / 11). For a member, that's the workspace root's file. Vendored should either write the override there or refuse loudly before writing anything, as it already does with vendor_lockfile_missing for a member without its own lock.
  • Actual: the override goes to two files pnpm ignores. The scan reports success, frozen installs fail, and non-frozen installs silently drop the patch.

OS × version (Linux, main 9c43dfc; each failing cell run twice)

pnpm layout scan root install --frozen-lockfile root plain install
9.15.9 shared-workspace-lockfile=false in .npmrc success pass (patched; pnpm 9 reads package.json pnpm.overrides) not run
10.34.5 .npmrc success pass (patched) not run
11.28.3 sharedWorkspaceLockfile: false in pnpm-workspace.yaml success fail ERR_PNPM_LOCKFILE_CONFIG_MISMATCH fail: exit 0, wiring dropped, upstream installed
12.8.1 pnpm-workspace.yaml success fail ERR_PNPM_LOCKFILE_CONFIG_MISMATCH fail: exit 0, wiring dropped, upstream installed

macOS and Windows weren't probed. The logic is path-only.

First bad release

Not a regression: release 4.0.0 does the same on pnpm 12.8.1 (frozen install ERR_PNPM_LOCKFILE_CONFIG_MISMATCH).

Suspect code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions