Skip to content

vendor --check reports a missing or corrupt vendored artifact as a raw Rust Debug value (Corrupt { reason: "vendor_workspace_artifact_missing" }) with no remedy, though socket-patch repair fixes it #1467

Closed

Description

[agent] Found by the scheduled Bun bug-hunt routine (ledger #306).

Summary

When vendor --check finds that a committed vendored artifact is missing or doesn't match the ledger, its reason is the Debug output of the internal ArtifactHealth enum:

pkg:npm/minimist@1.2.2: artifact verification failed: Corrupt { reason: "vendor_workspace_artifact_missing" }

The same text appears in the --json event's reason. It doesn't say which file is affected, and it doesn't give a remedy, even though socket-patch repair restores the artifact and turns the check green. Every other vendor --check drift reason names the cause and the next step ("wiring contested … delete the one the project does not install from", "dependency removed … scan --mode vendored --prune", "re-run socket-patch vendor").

On Bun this matters most for bun.lockb workspaces. Since #1442 (#1116), vendoring also writes a mirror of each patched tarball under every member, at packages/<m>/.socket/vendor/npm/<uuid>/. Losing a member mirror (a stray git clean, a .socket/ rule added to a member later, or a partial checkout) is now a realistic way for CI to go red. The CI log then shows only Corrupt { reason: "vendor_workspace_artifact_missing" }.

Impact

This is a UX and diagnosability issue, not a patching failure. The check correctly goes red (exit 1). But CI users get an internal identifier wrapped in Rust struct syntax, no path, and no fix. The member-mirror variant gives no sign that the root artifact is fine and only packages/a/... is missing.

Repro (Linux, main 15c2c83, Bun 1.4.3; patch API mocked locally)

mkdir ws && cd ws && git init -q
printf 'node_modules/\n*.tgz\n' > .gitignore
echo '{"name":"root","private":true,"workspaces":["packages/*"],"dependencies":{"minimist":"1.2.8"}}' > package.json
mkdir -p packages/a && echo '{"name":"a","version":"1.0.0","dependencies":{"minimist":"1.2.2"}}' > packages/a/package.json
printf '[install]\nsaveTextLockfile = false\n' > bunfig.toml
bun install
socket-patch scan --mode vendored --json        # success; writes the root artifact + packages/a mirror
git add -A && git commit -qm vendored

rm -rf packages/a/.socket
socket-patch vendor --check                     # exit 1
# pkg:npm/minimist@1.2.2: artifact verification failed: Corrupt { reason: "vendor_workspace_artifact_missing" }
socket-patch repair                             # "Redownloaded 1 vendored artifact."
socket-patch vendor --check                     # exit 0, "committed artifact and wiring verified"

The other ArtifactHealth variants print the same way:

Damage vendor --check reason (human and --json)
member mirror deleted (bun.lockb workspace) artifact verification failed: Corrupt { reason: "vendor_workspace_artifact_missing" }
member mirror bytes changed artifact verification failed: Corrupt { reason: "vendor_workspace_artifact_corrupt" }
root artifact bytes changed artifact verification failed: Corrupt { reason: "vendor_sha256_mismatch" }
root artifact deleted artifact verification failed: Missing

Expected vs actual

  • Expected (CLI_CONTRACT.md, "Vendored JVM support (v5)" → vendor --check): "Drift covers the committed artifact and its wiring … The reason names the cause", with a remedy, as the wiring reasons give. For an artifact failure, that means something like committed artifact packages/a/.socket/vendor/npm/<uuid>/minimist-1.2.2.tgz is missing (Bun workspace mirror); run \socket-patch repair` to restore it, then commit it`.
  • Actual: format!("artifact verification failed: {health:?}"), which gives no path, no remedy and Rust Debug syntax.

Matrix (Linux; each row reproduced twice)

Bun lock shape result
1.4.3 bun.lockb workspace, member mirror deleted / corrupted Debug reason, no remedy
1.2.23 bun.lockb workspace, member mirror deleted Debug reason, no remedy
1.4.3 bun.lock / bun.lockb root artifact deleted / corrupted Missing / Corrupt { reason: "vendor_sha256_mismatch" }
macOS / Windows — — untested (no probe branch this run); the formatting code is platform-independent

repair restores the artifact and its .gitignore / .gitattributes in every row. The root-artifact rows aren't Bun-specific: the format string is shared by every vendored ecosystem.

First bad: not a regression. The member-mirror rows are new reachable states since #1442.

Suspect code

  • crates/socket-patch-cli/src/commands/vendor.rs:1259: health => Some(format!("artifact verification failed: {health:?}")).
  • The reason strings come from crates/socket-patch-core/src/vendor/verify.rs:945 and crates/socket-patch-core/src/vendor/bun_workspace.rs:76 / :241.

Labels: bug, bughunt, pm:bun.

Activity

  1. mikolalysenko commented on Oct 13, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Claiming this issue (shared root cause: vendor --check formats a failed ArtifactHealth with Rust Debug instead of a cause + path + remedy). Branch: agent/fix-vendor-check-artifact-reason. Claim-ID: 2026-10-13T05:21:15Z-78ebfc


    Generated by Claude Code

  2. mikolalysenko commented on Oct 13, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Draft PR: #1468


    Generated by Claude Code

  3. added a commit that references this issue on Oct 13, 2026
    e4cffb4
  4. added a commit that references this issue on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions