You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vendored yarn classic exits 0 when .gitignore covers the vendored tarball (*.tgz, vendor/, .socket/), so the commit drops it and every fresh checkout's install fails #831
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
scan --mode vendored on a yarn classic project writes .socket/vendor/npm/<uuid>/<name>-<ver>.tgz and wires yarn.lock to it. It doesn't check whether git ignores that path. If the project's .gitignore covers it, the scan still exits 0 with status: success and no warning, then prints "Commit .socket/vendor/ and the updated lockfiles". The rewired yarn.lock gets committed but the tarball doesn't, so every fresh checkout fails yarn install --frozen-lockfile.
Three ordinary ignore rules trigger it:
*.tgz: GitHub's stock Node.gitignore ships this ("Output of 'npm pack'"), so most JS repos have it.
vendor/: common in polyglot repos (Go, PHP, Ruby). It matches .socket/vendor/ at any depth.
.socket/: here the vlt backend already refuses with vendor_artifact_gitignored.
The vlt backend handles exactly this. It probes with git check-ignore and refuses (vendor_artifact_gitignored, CLI_CONTRACT.md error-code table), and it writes a <uuid>/.gitignore with !* to re-include the payload. The yarn classic tarball backend does neither.
vendor --check (the CI gate) doesn't catch the broken checkout either:
Under *.tgz, the ledger is committed, so --check exits 1 (Missing).
Under vendor/ or .socket/, state.json is ignored as well. vendor --check then exits 0 with discovered: 0 while yarn.lock still resolves file:./.socket/vendor/npm/…. CLI_CONTRACT.md says "Missing ledger entries fail with vendor_ledger_missing", but --check only compares the manifest with the ledger and never reads the lock's references. (repair does notice them.)
Impact
On a typical JS repo, the documented vendored workflow (scan, commit, push) breaks CI and every teammate's install. The scan reports success, and with vendor/ or .socket/ ignored, vendor --check reports success too. Nothing points at the cause.
Repro (Linux, yarn 1.22.22; same on 1.7.0 / 1.10.1)
I used a local mock patch API: the self-contained mock.py from the ledger's run-18 probe workflow, which serves left-pad@1.3.0 with a marker prepended to index.js.
API="--api-url http://127.0.0.1:8787 --org o --api-token x"
mkdir p &&cd p && git init -q
echo'{"name":"p","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}'> package.json
printf'node_modules\n*.tgz\n'> .gitignore # or 'vendor/' or '.socket/'
yarn install && git add -A && git commit -qm init
socket-patch scan --mode vendored --vendor-source service --json --yes $API# exit 0, status success, warnings []
git add -A && git commit -qm vendored
git ls-files .socket # socket-patch.vendor.json + state.json only; no .tgz
git clone -q . ../fresh &&cd ../fresh
yarn install --frozen-lockfile # exit 1# error "./.socket/vendor/npm/1111…/left-pad-1.3.0.tgz": Tarball is not in network and can not be located in cache
socket-patch vendor --check # *.tgz: exit 1 (Missing); vendor/ or .socket/: exit 0, nothing discovered
socket-patch vex --output v.json $API# exit 1, vendor_artifact_missing / record_unavailable
Expected vs actual
Expected: the same treatment vlt gets (CLI_CONTRACT.md vendor_artifact_gitignored: "inside a git work tree, git check-ignore --no-index reports the new artifact's uuid directory as ignored… Refused before any write"). That means re-including the artifact through a <uuid>/.gitignore where a nested rule can override the ignore (*.tgz), and refusing before any write where it can't (vendor/, .socket/). vendor is documented as ejecting into a "committable .socket/vendor/" (CLI_CONTRACT.md command table). vendor --check should fail when a lockfile references .socket/vendor/<eco>/<uuid>/ that has no ledger entry (vendor_ledger_missing).
Actual: exit 0 with no warning, the tarball is never committed, and fresh frozen installs fail. With vendor/ or .socket/ ignored, vendor --check also exits 0.
Matrix (Linux, Node 22; scan exit / fresh-clone yarn install --frozen-lockfile / vendor --check in the clone)
yarn
*.tgz
vendor/
.socket/
1.7.0
0 / fail / 1
0 / fail / 0
0 / fail / 0
1.10.1
0 / fail / 1
0 / fail / 0
0 / fail / 0
1.22.22
0 / fail / 1
0 / fail / 0
0 / fail / 0
Each cell was reproduced twice on main 045d7ec. The yarn version doesn't matter; this is purely a socket-patch gap. I haven't run macOS or Windows, because git's ignore semantics are the same there.
Suspect code
crates/socket-patch-core/src/vendor/yarn_classic_lock.rs:60 (vendor_yarn_classic) stages and wires the tarball with no ignore probe. Compare crates/socket-patch-core/src/vendor/vlt_lock.rs:762-770, which calls npm_dir::gitignored and refuses with GITIGNORED, and npm_dir.rs:46 (UUID_GITIGNORE).
crates/socket-patch-cli/src/commands/vendor.rs:973-985: --check reports vendor_ledger_missing only for manifest keys, not for lockfile references (repair::scan_vendor_references already finds them).
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
scan --mode vendoredon a yarn classic project writes.socket/vendor/npm/<uuid>/<name>-<ver>.tgzand wiresyarn.lockto it. It doesn't check whether git ignores that path. If the project's.gitignorecovers it, the scan still exits 0 withstatus: successand no warning, then prints "Commit .socket/vendor/ and the updated lockfiles". The rewiredyarn.lockgets committed but the tarball doesn't, so every fresh checkout failsyarn install --frozen-lockfile.Three ordinary ignore rules trigger it:
*.tgz: GitHub's stock Node.gitignore ships this ("Output of 'npm pack'"), so most JS repos have it.vendor/: common in polyglot repos (Go, PHP, Ruby). It matches.socket/vendor/at any depth..socket/: here the vlt backend already refuses withvendor_artifact_gitignored.The vlt backend handles exactly this. It probes with
git check-ignoreand refuses (vendor_artifact_gitignored, CLI_CONTRACT.md error-code table), and it writes a<uuid>/.gitignorewith!*to re-include the payload. The yarn classic tarball backend does neither.vendor --check(the CI gate) doesn't catch the broken checkout either:*.tgz, the ledger is committed, so--checkexits 1 (Missing).vendor/or.socket/,state.jsonis ignored as well.vendor --checkthen exits 0 withdiscovered: 0whileyarn.lockstill resolvesfile:./.socket/vendor/npm/…. CLI_CONTRACT.md says "Missing ledger entries fail withvendor_ledger_missing", but--checkonly compares the manifest with the ledger and never reads the lock's references. (repairdoes notice them.)Impact
On a typical JS repo, the documented vendored workflow (scan, commit, push) breaks CI and every teammate's install. The scan reports success, and with
vendor/or.socket/ignored,vendor --checkreports success too. Nothing points at the cause.Repro (Linux, yarn 1.22.22; same on 1.7.0 / 1.10.1)
I used a local mock patch API: the self-contained
mock.pyfrom the ledger's run-18 probe workflow, which servesleft-pad@1.3.0with a marker prepended toindex.js.Expected vs actual
vendor_artifact_gitignored: "inside a git work tree,git check-ignore --no-indexreports the new artifact's uuid directory as ignored… Refused before any write"). That means re-including the artifact through a<uuid>/.gitignorewhere a nested rule can override the ignore (*.tgz), and refusing before any write where it can't (vendor/,.socket/).vendoris documented as ejecting into a "committable.socket/vendor/" (CLI_CONTRACT.md command table).vendor --checkshould fail when a lockfile references.socket/vendor/<eco>/<uuid>/that has no ledger entry (vendor_ledger_missing).vendor/or.socket/ignored,vendor --checkalso exits 0.Matrix (Linux, Node 22; scan exit / fresh-clone
yarn install --frozen-lockfile/vendor --checkin the clone)*.tgzvendor/.socket/Each cell was reproduced twice on main
045d7ec. The yarn version doesn't matter; this is purely a socket-patch gap. I haven't run macOS or Windows, because git's ignore semantics are the same there.Suspect code
crates/socket-patch-core/src/vendor/yarn_classic_lock.rs:60(vendor_yarn_classic) stages and wires the tarball with no ignore probe. Comparecrates/socket-patch-core/src/vendor/vlt_lock.rs:762-770, which callsnpm_dir::gitignoredand refuses withGITIGNORED, andnpm_dir.rs:46(UUID_GITIGNORE).crates/socket-patch-cli/src/commands/vendor.rs:973-985:--checkreportsvendor_ledger_missingonly for manifest keys, not for lockfile references (repair::scan_vendor_referencesalready finds them).*.jar). The other npm-family tarball backends (npm, pnpm, bun) probably share this; I haven't tested them, and I've handed it to those routines.