Repository navigation
socket-patch --update on a yarn-classic-installed copy says "managed by npm": npm update -g leaves a yarn global add install stale, and a yarn project is told to run npm install #1629
Description
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
This is the yarn classic twin of #1111 (pnpm, fixed) and #1621 (Bun, PR #1622, which explicitly keeps yarn on npm). When socket-patch was installed with yarn 1, socket-patch --update refuses with managed_install, says the binary "is managed by npm", and suggests an npm command. For a yarn global add install, that command does nothing:
| How it was installed | Hint on main 657fce2 |
What following the hint does |
|---|---|---|
yarn global add @socketsecurity/socket-patch (default global dir, e.g. ~/.config/yarn/global, /usr/local/share/.config/yarn/global as root) |
npm update -g @socketsecurity/socket-patch |
npm prints up to date, and the yarn copy stays on 4.0.0. yarn global upgrade @socketsecurity/socket-patch --latest moves it to 5.0.1. |
yarn global add with a custom --global-folder / global-folder (dir not named global) |
npm install @socketsecurity/socket-patch@latest |
Classified as a project, because the global folder holds yarn's package.json. Run from the user's cwd, the hint installs socket-patch into whatever project they're in. |
yarn add @socketsecurity/socket-patch in a project |
npm install @socketsecurity/socket-patch@latest |
npm 7+ does rewrite yarn.lock, and yarn install --frozen-lockfile still passes. But npm leaves a stray package-lock.json beside yarn.lock, so every later yarn run warns package-lock.json found … It is advised not to mix package managers. |
The passive update notice uses the same hint (crates/socket-patch-cli/src/update_notifier.rs:243).
Impact
Every yarn-global user is told to upgrade with a command that's a silent no-op. They stay on the old CLI while believing they've upgraded. Yarn project users get a second npm-family lock beside yarn.lock, which socket-patch's own hosted and vendored modes then also see.
Repro (Linux, Node 22, real yarn; run as a scratch user or with a scratch HOME)
export SOCKET_NO_UPDATE_CHECK=1
M=/path/to/socket-patch/target/release/socket-patch # main 657fce2
# Global
yarn global add @socketsecurity/socket-patch@4.0.0
GD=$(yarn global dir)
for f in $(find $GD -path '*linux-x64*' -name socket-patch -type f); do cp $M $f; done
$(yarn global bin)/socket-patch --update --yes
# Error: … (…/yarn/global/node_modules/@socketsecurity/socket-patch-linux-x64-gnu/socket-patch) is managed by npm;
# update it with `npm update -g @socketsecurity/socket-patch` instead, or pass --force … (exit 1)
npm update -g @socketsecurity/socket-patch # "up to date in 233ms"
grep '"version"' $GD/node_modules/@socketsecurity/socket-patch/package.json # still "4.0.0"
yarn global upgrade @socketsecurity/socket-patch --latest # control: -> "5.0.1"
# Project
mkdir proj && cd proj
echo '{"name":"proj","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
yarn add @socketsecurity/socket-patch@4.0.0
for f in $(find node_modules/@socketsecurity -path '*linux-x64*' -name socket-patch -type f); do cp $M $f; done
node_modules/.bin/socket-patch --update --yes # … managed by npm; update it with `npm install @socketsecurity/socket-patch@latest` …
npm install @socketsecurity/socket-patch@latest # writes package-lock.json beside yarn.lock
yarn install --frozen-lockfile # passes, but: "warning package-lock.json found …"The refusal happens before any network I/O.
Expected vs actual
CLI_CONTRACT.md:1100 says: "every other channel is refused with that channel's own upgrade command", and the managed-install row says the refusal "names the owning manager". Expected for a yarn 1 install: label yarn, and:
- a yarn global store (the
globaldir fromyarn global dir, which holds yarn's ownpackage.json+yarn.lock):yarn global add @socketsecurity/socket-patch@latest.yarn global upgrade … --latestalso works. - a project whose outermost
node_modulesholder hasyarn.lock(and no berry.yarnrc.yml/__metadata):yarn add @socketsecurity/socket-patch@latest.
Actual: channel_label_for reports npm, and upgrade_hint_for returns npm commands. Row CLI_CONTRACT.md:1118 says "otherwise global (including a yarn global store …): npm update -g". That row contradicts line 1100, and it's the same catch-all #1111 / #1621 called the defect: npm update -g never looks in yarn's global dir.
OS × version
| OS | yarn | Shape | Hint | Following the hint |
|---|---|---|---|---|
| Linux | 1.22.22 | global (default dir) | npm update -g … |
no-op, stays 4.0.0 (×2) |
| Linux | 1.10.1 | global (default dir) | npm update -g … |
no-op, stays 4.0.0 |
| Linux | 1.22.22 | global, custom --global-folder |
npm install …@latest |
wrong target (not run) |
| Linux | 1.22.22 | project | npm install …@latest |
stray package-lock.json, yarn warns; frozen install still passes |
| Linux | any | yarn global upgrade … --latest (control) |
n/a | upgrades to 5.0.1 |
macOS and Windows weren't probed. The classification is path-based (%LOCALAPPDATA%\Yarn\Data\global\node_modules takes the same global branch), so they should behave the same way. Not a regression: the code says yarn has "no dedicated hint yet".
Suspect code
crates/socket-patch-core/src/update/channel.rs:198(node_manager): "Anything else is npm, which also covers yarn and Bun (no dedicated hint yet)". There's noYarnvariant.crates/socket-patch-core/src/update/channel.rs:144(upgrade_hint_for) and:171(channel_label_for).crates/socket-patch-core/src/update/channel.rs:268(is_global_npm_install): it treats a yarnglobalstore as an npm global.crates/socket-patch-cli/CLI_CONTRACT.md:1118.- PR Fix Bun installs getting npm self-update hints (#1621) #1622 (open, Bun) touches the same function and keeps a test asserting the yarn global store gets
npm update -g, so the two will need reconciling.
Reported to the Yarn classic routine as a handover from the Bun routine (#1621). No probe runs (Linux only).
Activity
yarn-classic: run 46 ledger (#1629)
mikolalysenko commentedon Oct 17, 2026
[agent] Triaged:
priority:p1(yarn classic / npm family). Confirmed on main7d3086f:node_manager(crates/socket-patch-core/src/update/channel.rs) has no Yarn variant ("Anything else is npm, which also covers yarn and Bun"), sochannel_label_forsays npm andupgrade_hint_forgivesnpm update -g/npm install. This isn't a duplicate.Shares root cause with #1621:
update::channel::node_manageronly models npm, pnpm and vlt, so every other npm-family manager falls through to npm's label and hint. Will be fixed together. #1621 is being fixed in PR #1622, which is ready and green but keeps yarn on npm (it asserts that a yarnglobalstore getsnpm update -g). #1629 needs a follow-up on top of #1622, or #1622 can be widened if its owner takes it back.Generated by Claude Code