rust-lang/cargo · error

dupes must be in sync

Error message

dupes must be in sync

What it means

Invariant in `cargo install`/`uninstall` freshness tracking: `self.v2.installs.get(dupe_pkg_id).expect("dupes must be in sync")`. When a duplicate package is found, cargo assumes it has a matching install record in the `v2` tracker. The panic fires if a duplicate package id is not present in the installs map.

Source

Thrown at src/ops/common_for_install_and_uninstall.rs:216

                _ => None,
            })
            .collect();

        // If both sets are the same length, that means all duplicates come
        // from packages with the same name.
        if matching_duplicates.len() == duplicates.len() {
            // Determine if it is dirty or fresh.
            let source_id = pkg.package_id().source_id();
            if source_id.is_path() {
                // `cargo install --path ...` is always rebuilt.
                return Ok((Freshness::Dirty(DirtyReason::Forced), duplicates));
            }
            let is_up_to_date = |dupe_pkg_id| {
                let info = self
                    .v2
                    .installs
                    .get(dupe_pkg_id)
                    .expect("dupes must be in sync");
                let precise_equal = if source_id.is_git() {
                    // Git sources must have the exact same hash to be
                    // considered "fresh".
                    dupe_pkg_id.source_id().has_same_precise_as(source_id)
                } else {
                    true
                };

                dupe_pkg_id.version() == pkg.version()
                    && dupe_pkg_id.source_id() == source_id
                    && precise_equal
                    && info.is_up_to_date(opts, target, &exes)
            };
            if matching_duplicates.iter().all(is_up_to_date) {
                Ok((Freshness::Fresh, duplicates))
            } else {
                Ok((Freshness::Dirty(DirtyReason::Forced), duplicates))
            }

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Inspect `~/.cargo/.crates2.json` for duplicate/stale entries; back it up first.
  2. Remove the orphaned install: `cargo uninstall <crate>` for the listed duplicate, or delete the stale entry from `.crates2.json`.
  3. If the tracker is badly corrupted, remove `.crates2.json` (you lose the install ledger) and reinstall crates as needed.
  4. Report a cargo bug with the contents of `.crates2.json` (redact tokens) if it reproduces on fresh state.
Defensive patterns

Strategy: validation

Validate before calling

// Before install/uninstall freshness checks, back up and validate .crates2.json.
let tracker = std::fs::read("~/.cargo/.crates2.json")?;
let parsed: serde_json::Value = serde_json::from_slice(&tracker)?;
assert!(parsed["installs"].is_object(), "corrupted install tracker");

Prevention

When it happens

Trigger: Running `cargo install` (or `cargo uninstall`) when the on-disk install tracking metadata (`~/.cargo/.crates2.json`) lists duplicate package ids but the install-info entries disagree — i.e. the duplicates set and the installs map are inconsistent.

Common situations: Corrupted `.crates2.json` from a crash during install/uninstall; manual editing of the tracker; a cargo bug leaving a stale duplicate entry; mixed cargo versions writing the tracker with different id formats (e.g. git precise-fragment changes).

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/e14dd66f0a6e6199.json. Report an issue: GitHub.