Skip to content

Fix yarn copies with invalid manifest names (#1598) - #1605

Open
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
mainfrom
agent/fix-yarn-copy-invalid-identity
Open

Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
mainfrom
agent/fix-yarn-copy-invalid-identity

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #1598

Summary

A yarn portal: / link: / file: copy whose package.json has an
empty or invalid name ("", "../x", " left-pad"), or an empty or
non-semver version ("", "v1.3.0"), is now treated as naming no
package or no version. This is the same rule #1586 applies to a missing
key. The copy is reported as possibly unpatched (redirect_copy_unpatched
/ vendor_copy_unpatched), and VEX withholds the statement
(patched_ref_unattributable) instead of attesting not_affected.

Root cause

CopyRef::identity (formats/yarn/copy.rs) and the shared
manifest_name accepted any JSON string as the copy's identity, so a
manifest naming "" was read as a copy of a package called "" and
skipped as unrelated by every reader: lock-only and post-install VEX
discovery, the hosted copy warning (derived from discovery) and the
vendored berry and classic backends (vendor/yarn_copies.rs).

Fix

  • package_name validates with is_registry_package_name
    (validate-npm-package-name's validForOldPackages, already used by the
    vlt reader). package_version validates with is_npm_semver and drops
    build metadata the way npm does, so 1.3.0+build is 1.3.0.
  • manifest_name moved next to them in copy.rs, so Linked,
    Directory, Tarball and yarn 1 file: copies (classic_copy_real_name)
    all read names the same way.
  • docs/ecosystems.md documents the rule.

Tests (red → green)

Issue variant Test
portal:/link: + empty / ../x / leading-space name, hosted hosted_memory_engine::issue_1598_berry_invalid_manifest_name_or_version_is_named (CLI)
portal:/link: + empty / v version same, plus vex::discover::yarn::tests::issue_1598_invalid_manifest_name_or_version_contests
berry file: directory with empty / invalid name issue_1598_invalid_manifest_name_or_version_contests
yarn 1 file: directory and tarball with an invalid name issue_1598_invalid_manifest_name_or_version_contests
unit: every copy kind, npm-invalid names, non-semver versions, build metadata formats::yarn::copy::tests::invalid_manifest_name_or_version_identifies_nothing

Without the fix (core changes stashed), the CLI test fails with
portal {"name":"","version":"1.3.0"}: [] left: 0, and both core tests fail
(linked "" left: Some(("", "1.3.0"))). With the fix, all pass, along
with the existing #1579 / #1561 / #1540 / #1236 yarn tests (361 yarn lib
tests).

Local gates on a3a6d63:

  • cargo fmt --all -- --check: clean. cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test --workspace --all-features --no-fail-fast: 14584 passed, 10 failed. All 10 come from the sandbox, not this diff. Eight are
    read-only-permission 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).
    e2e_bun_lockb::binary_shared_bundled_record_hosted_pin_is_managed
    needs patches-api.socket.dev, which the sandbox proxy blocks. None of them
    touch yarn code.
  • scripts/yarn-classic-vex-matrix.sh 1.22.22: pass.
  • scripts/yarn-berry-vex-matrix.sh 4.18.0: can't run here, because corepack can't
    fetch yarn 4.18.0 behind the sandbox proxy. CI's yarn-berry job covers it.

/code-review high: two findings (names npm can't carry, such as zero-width
space, ? or @/x; versions with build metadata or numbers too large for npm)
were fixed in a3a6d63 by reusing the existing npm validators. The
helper-cycle cleanup was applied too. Not fixed: one extra JSON parse per
linked copy (negligible), and npm package-lock file: entries reading
name literally (vex/discover/npm.rs). That is a different lock format and
reader, and it's left as a follow-up rather than widening this PR.

🤖 Generated with Claude Code


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A yarn portal:/link:/file: copy whose package.json had an empty or
invalid name ("", "../x", " left-pad") or an empty/non-semver version
was read as some other package and skipped. Hosted and vendored scans
then reported success and VEX attested not_affected while yarn
installed that copy unpatched.

Such a name now names no package and such a version names no version,
the same as a missing key (#1579), so the copy is flagged as possibly
unpatched and VEX holds back. Yarn 1 file: copies share the reader and
get the same treatment.

Fixes #1598

Assisted-by: Claude Code:claude-opus-5-5
A copy whose package.json name has characters npm never allows
("left-pad?", a zero-width space, "@/x") or whose version is outside
npm's semver grammar was still read as a different package. Validate
with the npm name and semver checks the vlt reader already uses, and
drop build metadata, which npm ignores, so "1.3.0+build" counts as
1.3.0.

Refs #1598

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 a3a6d63. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 16, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Labeled Ready for review at head a3a6d63b.

  • CI: 36/36 green (50 skipped), no main-wide failures.
  • Bugbot: reviewed a3a6d63b, no findings.
  • Mergeable, no CHANGELOG.md changes. Waiting on a human approval.
  • Slack announcement could not be sent from this run; the next run will retry.

Generated by Claude Code

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

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

2 participants