Repository navigation
socket-patch --update on a pnpm-installed copy says "managed by npm" and gives an npm command: npm update -g leaves a pnpm global install stale, and npm install …@latest in a pnpm project breaks the next pnpm install --frozen-lockfile #1111
Description
[agent] Found by the scheduled pnpm bug-hunt routine (ledger #303).
Summary
When socket-patch was installed with pnpm (pnpm add -g @socketsecurity/socket-patch or pnpm add @socketsecurity/socket-patch in a project), socket-patch --update refuses with managed_install and says the binary "is managed by npm". The upgrade command it gives is an npm command, and neither one works for a pnpm install:
- pnpm global install →
npm update -g @socketsecurity/socket-patch. npm's global prefix doesn't hold the package, so npm prints "up to date" and the pnpm copy stays on the old version. - pnpm project dependency (new on main) →
npm install @socketsecurity/socket-patch@latest. Running it in a pnpm project does update the binary, but it also writes apackage-lock.json, bumpspackage.jsonto^4.0.0and leavespnpm-lock.yamlon the old version. The nextpnpm install --frozen-lockfile(the CI default) then fails withERR_PNPM_OUTDATED_LOCKFILE. The straypackage-lock.jsonalso becomes a second npm-family lock that socket-patch's own hosted/vendored modes will see from then on.
The passive update notifier uses the same hint (crates/socket-patch-cli/src/update_notifier.rs:240), so users see it on ordinary runs whenever a newer release exists.
Impact
Every user who installed socket-patch through pnpm is told to upgrade with a command that either does nothing (global) or breaks their pnpm project's frozen install (project). vlt already gets its own command (vlt install … / vlx …); pnpm doesn't.
Repro (Linux, Node 22, pnpm 9.15.9 / 10.34.6 / 12.10.1, all in scratch dirs)
export PNPM_HOME=$PWD/home/pnpm npm_config_prefix=$PWD/npmprefix PATH=$PWD/home/pnpm:$PWD/home/pnpm/bin:$PATH
# Global
pnpm add -g @socketsecurity/socket-patch@3.3.0
socket-patch --update # (main binary in place of the published one) → "managed by npm; update it with `npm update -g @socketsecurity/socket-patch`"
npm update -g @socketsecurity/socket-patch # "up to date"
socket-patch --version # still 3.3.0
# Project
mkdir proj && cd proj
echo '{"name":"proj","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
pnpm add @socketsecurity/socket-patch@3.3.0
./node_modules/.bin/socket-patch --update # main → "managed by npm; update it with `npm install @socketsecurity/socket-patch@latest`"
npm install @socketsecurity/socket-patch@latest # writes package-lock.json, package.json now "^4.0.0", pnpm-lock.yaml still 3.3.0
pnpm install --frozen-lockfile # ERR_PNPM_OUTDATED_LOCKFILETo test main's hint I installed the published 4.0.0 / 3.3.0 package with pnpm and copied main's target/release/socket-patch over the platform binary (node_modules/.pnpm/@socketsecurity+socket-patch-linux-x64-gnu@…/…/socket-patch). The refusal happens before any network I/O.
The commands that do work: pnpm add -g @socketsecurity/socket-patch@latest (global: 3.3.0 → 4.0.0) and pnpm add @socketsecurity/socket-patch@latest (project: 3.3.0 → 4.0.0, and --frozen-lockfile still passes). I checked both on 10.34.6 and 12.10.1.
Expected vs actual
CLI_CONTRACT.md (§ self-update, line 975): "every other channel is refused with that channel's own upgrade command." Expected: a pnpm install is labelled pnpm and pointed at pnpm add -g @socketsecurity/socket-patch@latest (global) or pnpm add @socketsecurity/socket-patch@latest (a project whose root holds pnpm-lock.yaml, or whose binary path runs through node_modules/.pnpm), the same way vlt projects get vlt install ….
Actual: the contract's own table (line 993) sends "a yarn/pnpm global store" to npm update -g, and the code sends pnpm projects to npm install. Neither is pnpm's command. So the table row is the defect, not a documented limitation.
OS × version
| OS | pnpm | layout (canonical exe) | hint on main | hint on 4.0.0 | following the hint |
|---|---|---|---|---|---|
| Linux | 9.15.9 | global global/5/.pnpm/… |
npm update -g … |
same | no-op, stays 3.3.0 (twice) |
| Linux | 9.15.9 | project node_modules/.pnpm/… |
npm install …@latest |
npm update -g … |
ERR_PNPM_OUTDATED_LOCKFILE + stray package-lock.json |
| Linux | 10.34.6 | global global/5/.pnpm/… |
npm update -g … |
same | no-op (twice) |
| Linux | 10.34.6 | project | npm install …@latest |
npm update -g … |
ERR_PNPM_OUTDATED_LOCKFILE (twice) |
| Linux | 12.10.1 | global global/v11/<hash>/node_modules/.pnpm/… |
npm update -g … |
same | no-op |
| Linux | 12.10.1 | project | npm install …@latest |
npm update -g … |
ERR_PNPM_OUTDATED_LOCKFILE |
The path logic is OS-independent (%LOCALAPPDATA%\pnpm\global\… on Windows takes the same global branch), but I didn't probe macOS or Windows. 4.0.0 is wrong too (it says npm update -g even for a project install), so this isn't a regression. Main changed the project-install text to npm install …@latest, which is the variant that actively breaks the lockfile.
Suspect code
crates/socket-patch-core/src/update/channel.rs:134(upgrade_hint_for): special-cases vlt / vlx but not pnpm. Anode_modules/.pnpmsegment in the canonical path, apnpm-lock.yamlin the holder dir, or apnpm/globalstore all identify pnpm.crates/socket-patch-core/src/update/channel.rs:171(is_global_npm_install) treats the pnpmglobalstore as an npm global.channel_label(channel.rs:~200) reports "npm" for everynode_modulesinstall.- CLI_CONTRACT.md line 993 (the npm row of the managed-install table).
The same table row also covers a yarn global store. I didn't test yarn or Bun here.
No probe runs (Linux only).
Backlog review — 2026-10-08
Priority: P1 → P2. Self-update prints the wrong package-manager command. This is actionable, but the bad install requires following the incorrect advice.
Activity
mikolalysenko commentedon Oct 8, 2026
[agent] Triaged: priority:p1 (pnpm). This is a self-update channel bug in
update/channel.rs:upgrade_hint_for,is_global_npm_installandchannel_labelhave no pnpm case. CLI_CONTRACT.md's managed-install table row needs to change with it. No open PR covers it yet.Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
v5 release blocker (P1). The v5 upgrade instruction must use the package manager that installed the CLI. The current npm command is wrong for pnpm and can introduce another lockfile.
This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.
mikolalysenko commentedon Oct 9, 2026
[agent] Claiming for v5 blocker burn-down (shared root cause: update/channel.rs has no pnpm case, so pnpm installs are labelled npm and given npm commands). Branch: agent/v5-update-pnpm-channel. Claim-ID: 2026-10-09T16:41:47Z-65fd29
Give pnpm installs pnpm upgrade commands