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
- Inspect `~/.cargo/.crates2.json` for duplicate/stale entries; back it up first.
- Remove the orphaned install: `cargo uninstall <crate>` for the listed duplicate, or delete the stale entry from `.crates2.json`.
- If the tracker is badly corrupted, remove `.crates2.json` (you lose the install ledger) and reinstall crates as needed.
- 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
- Always uninstall via `cargo uninstall`, never by hand-editing `.crates2.json`.
- Back up `~/.cargo/.crates2.json` before experimentation.
- If duplicates appear, remove the stale entry with `cargo uninstall`.
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
- validation ensures this is a table
- artifact-dir was not locked
- artifact dep
- already loaded config values
- env var was not array
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/e14dd66f0a6e6199.json.
Report an issue: GitHub.