Skip to content

bug(pacquet/lockfile): PkgNameVerPeer::without_peer panics with MismatchParenthesis on some snapshot keys #11939

Description

@zkochan

Summary

pacquet install panics on the vlt babylon fixture under the node_modules and lockfile+node_modules variations. The crash sites trace to PkgNameVerPeer::without_peer:

× Main thread panicked.
├─▶ at pacquet/crates/lockfile/src/pkg_name_ver_peer.rs:60:14
╰─▶ a prefix + the displayed version is always a valid PkgVerPeer:
    MismatchParenthesis

Found while verifying #11934 against the published vlt benchmark cells (#11902 comment).

Why it panics

pub fn without_peer(&self) -> PkgNameVerPeer {
    let prefix = self.suffix.prefix();
    let bare_input = format!("{}{}", prefix, self.suffix.version());
    let bare = bare_input
        .parse::<PkgVerPeer>()
        .expect("a prefix + the displayed version is always a valid PkgVerPeer");
    PkgNameVerPeer::new(self.name.clone(), bare)
}

The expectation is that prefix + version is always a valid PkgVerPeer. On the babylon fixture some snapshot key's version() output contains unbalanced parens — likely a sub-spec where the resolver retained a ( from a peer-suffix split point.

Impact on the vlt chart

Variation babylon ratio Cause
node_modules 38.40 Panic — pacquet exits non-zero, the timeout wrapper still records wall time
lockfile+node_modules 37.74 Same panic
cache+lockfile+node_modules 9.22 Same panic on a subset of iterations
cache+node_modules 9.30 Same panic on a subset of iterations

The "DNF" ratios on the published chart at https://benchmarks.vlt.sh/#/package-managers/average for these cells almost certainly come from the same panic combined with the now-fixed linkWorkspacePackages gap (#11929/#11930).

Repro

git clone https://github.com/vltpkg/benchmarks.git /tmp/vlt-benchmarks
cd /tmp/vlt-benchmarks
BENCH_INCLUDE="pacquet" BENCH_RUNS=1 bash scripts/benchmark.sh babylon lockfile+node_modules
cat results/babylon/lockfile+node_modules/pacquet-output-*.log

What needs to happen

  1. Identify the snapshot key shape that produces a version() string with unbalanced parens. (Tracing during the warmup install on a checked-out babylon would print the exact key.)
  2. Decide whether version() should be invariant ("always balanced") and fix the caller that emits the bad value, OR whether without_peer should construct the result without re-parsing through PkgVerPeer::from_str.
  3. Either way, drop the .expect(...) on this path — it's a recoverable parse error, not an invariant violation. A failed strip should fall through to the caller's error handling rather than abort the install.

Related: this is the residual cause of babylon row entries above 1.0× in the post-0.2.10 chart (see #11902 comment). Once this lands the babylon legitimate-perf measurements become possible.


Written by an agent (Claude Code, claude-opus-4-7).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions