{"id":"9ed4b1a87a644442","repo":"rust-lang/cargo","slug":"package-is-specified-twice-in-the-lockfile","errorCode":null,"errorMessage":"package `{}` is specified twice in the lockfile","messagePattern":"package `(.+?)` is specified twice in the lockfile","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/resolver/encode.rs","lineNumber":187,"sourceCode":"            packages.insert(0, root);\n        }\n        packages\n    };\n\n    // `PackageId`s in the lock file don't include the `source` part\n    // for workspace members, so we reconstruct proper IDs.\n    let live_pkgs = {\n        let mut live_pkgs = HashMap::default();\n        let mut all_pkgs = HashSet::default();\n        for pkg in packages.iter() {\n            let enc_id = TomlLockfilePackageId {\n                name: pkg.name.clone(),\n                version: Some(pkg.version.clone()),\n                source: pkg.source.clone(),\n            };\n\n            if !all_pkgs.insert(enc_id.clone()) {\n                anyhow::bail!(\"package `{}` is specified twice in the lockfile\", pkg.name);\n            }\n            let id = match pkg\n                .source\n                .as_ref()\n                .map(|source| SourceId::from_url(&source.source_str()))\n                .transpose()?\n                .or_else(|| get_source_id(&path_deps, &pkg).copied())\n            {\n                // We failed to find a local package in the workspace.\n                // It must have been removed and should be ignored.\n                None => {\n                    debug!(\"path dependency now missing {} v{}\", pkg.name, pkg.version);\n                    continue;\n                }\n                Some(source) => PackageId::try_new(&pkg.name, &pkg.version, source)?,\n            };\n\n            // If a package has a checksum listed directly on it then record","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/resolver/encode.rs#L169-L205","documentation":"Raised in `into_resolve` while decoding `Cargo.lock`: two entries in the lockfile's `[[package]]` list produce identical encodable IDs (name + version + source). Cargo dedupes via a `HashSet` (`all_pkgs.insert`) and bails on the second insert, because the lockfile format requires each package to appear exactly once.","triggerScenarios":"A manually or programmatically corrupted `Cargo.lock` containing two `[[package]]` blocks with the same name/version/source. Also possible from a botched merge conflict resolution in `Cargo.lock`, or from a tool that rewrites lockfiles incorrectly.","commonSituations":"Git merge conflicts in `Cargo.lock` resolved by keeping both sides; third-party tools (lockfile editors, dependency scanners) writing duplicate entries; hand-editing `Cargo.lock`.","solutions":["Regenerate the lockfile: delete `Cargo.lock` and run `cargo generate-lockfile` or `cargo build`.","Resolve git merge conflicts in `Cargo.lock` by running `cargo check` rather than hand-merging.","Audit `Cargo.lock` for duplicate `[[package]]` entries with identical name/version/source and remove the stale one."],"exampleFix":"# before: two [[package]] entries for serde 1.0.184\n# after\ngit checkout --theirs Cargo.lock && cargo generate-lockfile","handlingStrategy":"validation","validationCode":"# Pre-commit check: never hand-merge Cargo.lock — regenerate instead.\n# Validate the lockfile parses cleanly:\ncargo metadata --no-deps --offline >/dev/null || cargo generate-lockfile","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve `Cargo.lock` merge conflicts by deleting the file and running `cargo generate-lockfile`, not by hand-merging.","Run `cargo check` in pre-commit hooks to validate the lockfile.","Avoid third-party tools that rewrite `Cargo.lock` by hand."],"tags":["lockfile","duplicate","corruption","merge"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}