Repository navigation
Fix yarn berry missing portal:/link: copies (#1561) - #1571
Mikola Lysenko (mikolalysenko) merged 6 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A yarn berry portal: or link: dependency under another name whose relative target directory is missing (for example a git submodule CI didn't check out) is silently dropped today: hosted and vendored scans report success and vex attests not_affected, while the install that has the directory links an unpatched copy. Add regression tests for #1561 on the vex discovery, vendored berry and hosted engine paths. They fail on main. Assisted-by: Claude Code:claude-opus-5-5
A yarn berry portal: or link: dependency under another name gets its package and version only from its package.json. When a relative target was missing (an uninitialized git submodule, a generated or gitignored directory) or its package.json couldn't be read, the copy was treated like a link: to a plain asset directory and dropped. Scans reported success and vex attested not_affected, while the install that had the directory linked an unpatched copy. Such a copy is now unknown, like an absolute one: hosted warns redirect_copy_unpatched, vendored warns vendor_copy_unpatched, and vex withholds every package the lock wires. A link: to a directory that exists with no package.json is still ignored. Fixes #1561 Assisted-by: Claude Code:claude-opus-5-5
Say that a relative portal: or link: copy whose target is missing is treated like an absolute one, and that a link: to a directory with no package.json is not a package copy. Refs #1561 Assisted-by: Claude Code:claude-opus-5-5
A git submodule CI never checked out leaves an empty directory, not a missing one, and a package.json that is a Git LFS pointer or encrypted blob reads fine but is no JSON. Both were still dropped like a link: to plain assets, so scans stayed clean and vex attested not_affected. An empty target directory and a package.json that doesn't parse now make the copy unknown too. Only a non-empty directory with no package.json, or a parsed manifest with no versioned package, is still ignored. Also pass the root as "" to the project view so hosted and disk agree on portal:. targets, and share the hosted test fixture. Refs #1561 Assisted-by: Claude Code:claude-opus-5-5
Refs #1561 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 1018077. Configure here.
|
Ready for review at
Slack announcement not sent this run (Slack send unavailable); the next run retries. Generated by Claude Code |
Final review briefWhat it does. A yarn berry Risk: low. Fail-closed change in one predicate shared by two callers; the worst case is an extra warning, never a missed copy. A Look here
Verified
Changes I made: none. Open questions: none blocking. Known trade-off, written up in the PR description: in hosted in-memory mode a relative linked copy whose target files the host didn't send is now flagged rather than dropped (fail-closed, matching #1516). Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1561
Summary
A yarn berry
portal:/link:dependency under another name ("lp2": "portal:./vend/lp") whose relative target can't be read is now treated as an unknown copy of any version of any package, the same as an absolute one (#1540). Hosted warnsredirect_copy_unpatched, vendored warnsvendor_copy_unpatched, andvexwithholds every package that lock wires. Before this change the copy was dropped: scans reported success and VEX attestednot_affected, while the install with the target present linked unpatched bytes asnode_modules/lp2.Root cause
Such a copy's lock version is the placeholder
0.0.0-use.local, so only itspackage.jsonsays what it is. When reading that manifest yielded no identity, both the vendored/hosted copy finder (vendor/yarn_copies.rsother_name_copies) and VEX lockfile discovery (vex/discover/yarn.rsrecord_copies) treated "the read failed" the same as "read and found to hold no versioned package" (alink:to plain assets), and skipped the copy unless the path was absolute.Fix
One shared predicate,
yarn_copies::linked_copy_unknown, used by both callers. A linked copy is unknown when it is:portal:/link:copy with an absolute path, so hosted and vendored scans succeed and every VEX path attests not_affected while that copy installs unpatched #1540),package.jsonthat isn't a readable regular file, or isn't JSON (a Git LFS pointer, an encrypted blob).It is not a package copy, and so stays ignored per the #1551 review intent, only when it is a non-empty directory with no
package.json, or a parsed manifest naming no versioned package.CopyRef::is_unread_linkedis folded into the predicate. The berry vendored warning keeps the "installs a package" wording for every unidentified linked copy.docs/ecosystems.mdnow spells out the missing / empty / LFS cases.Tests (red → green)
vex::discover::yarn::tests::issue_1561_unreadable_relative_portal_and_link_targets_contest_every_ref(portal/link × missing, empty, manifest-is-a-directory, LFS pointer)vendor::yarn_berry_lock::tests::issue_1561_missing_relative_portal_and_link_targets_are_named(portal/link × missing, empty, LFS pointer; plain asset directory control stays unnamed)vendor_copy_unpatchedhosted_memory_engine::issue_1561_berry_missing_relative_portal_and_link_copies_are_named(+ control: a target whosepackage.jsonnames another package is not flagged)redirect_copy_unpatchedThe first commit (87d9321) holds only the tests, which failed on main as listed. The
empty/lfs-pointervariants came from the pre-ready/code-review highpass.Commands run locally (Linux, as root):
cargo fmt --all -- --check: okcargo clippy --workspace --all-features -- -D warnings: okcargo test --workspace --all-features --no-fail-fast: 14,563 passed. The 10 failures are environment-only and touch no yarn code: write-failure / read-only-parent tests that can't fail when run as root (e.g.copy_tree::relax_loop_must_not_traverse_symlinked_root,pypi_requirements::wire_failure_rolls_back_already_written_files,repair_*,redirect_json_mode_write_failures_emit_error_envelope), ande2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed, which needs the live patch API (sandbox tunnel blocked). CI runs non-root with network.SOCKET_PATCH_YARN_E2E_REQUIRED=1):e2e_redirect_yarn_berry_build37/37,e2e_vendor_yarn_berry_build44/44,e2e_yarn4_pnpm_linker_build40/40,e2e_yarn4_workspaces_build39/39.npm/,pypi/,gem/) only dispatch to the binary and need no change./code-review high: findings not fixed
package.jsonin the snapshot (the new control test shows such a file is read and honoured). When the host leaves it out, the copy is now flagged as possibly unpatched instead of silently dropped. Dropping it was the fail-open this issue reports. Flagging matches how memory mode already treats an unreadfile:directory copy at its lock version (Yarn classic renamed-copy detection (#1489) misses afile:copy outside the project root and a tarball whose root isn'tpackage/, so scans succeed and VEX attests while that copy installs unpatched #1516). Teaching path selection to fetch linked targets' manifests would mean parsing yarn.lock before the fetch, which is a separate change. Follow-up if wanted.other_name_copiesprobes withProjectView::Disk(syncis_dir) rather than group-commit-aware helpers. The read beside it usesread_regular_to_byteson the same disk path. No caller runs this inside an open group commit before the lock rewrite, and onestatper linked candidate is negligible. Left as is.🤖 Generated with Claude Code
Generated by Claude Code