{"record":{"id":"dccb8058fd89f6bb","repo":"rust-lang/cargo","slug":"several-patch-entries-resolving-to-same-versio","errorCode":null,"errorMessage":"several `[patch]` entries resolving to same version `{} v{}`\nhelp: check `{}` patch definitions for `{}` in {}","messagePattern":"several `\\[patch\\]` entries resolving to same version `(.+?) v(.+?)`\nhelp: check `(.+?)` patch definitions for `(.+?)` in (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/workspace/registry.rs","lineNumber":460,"sourceCode":"                    url,\n                    orig_patch.loc\n                ));\n            }\n            Ok(summary)\n        }).collect::<CargoResult<Vec<_>>>()?;\n\n        let mut name_and_version = HashSet::default();\n        for summary in unlocked_summaries.iter() {\n            let name = summary.package_id().name();\n            let version = summary.package_id().version();\n            if !name_and_version.insert((name, version)) {\n                let duplicate_locations = patch_deps\n                    .iter()\n                    .filter(|&p| p.0.dep.package_name() == name)\n                    .map(|p| format!(\"`{}`\", p.0.loc))\n                    .unique()\n                    .join(\", \");\n                return Err(anyhow::anyhow!(\n                    \"several `[patch]` entries resolving to same version `{} v{}`\\n\\\n                    help: check `{}` patch definitions for `{}` in {}\",\n                    name,\n                    version,\n                    name,\n                    url,\n                    duplicate_locations\n                ));\n            }\n        }\n\n        // Calculate a list of all patches available for this source.\n        let mut ids = Vec::new();\n        for (summary, (_, lock)) in unlocked_summaries.iter().zip(patch_deps) {\n            ids.push(summary.package_id());\n            // This is subtle where the list of `ids` for a canonical URL is\n            // extend with possibly two ids per summary. This is done to handle\n            // the transition from the v2->v3 lock file format where in v2","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/rust-lang/cargo/blob/98a09e7e7d62850f14e5b6132101fc1edd19a16f/src/workspace/registry.rs#L442-L478","documentation":"Multiple `[patch]` entries that resolve the same package to the same `(name, version)` pair create ambiguity — Cargo cannot choose between them. After collecting all unlocked summaries, the registry builds a `HashSet` of `(name, version)` and bails on the first duplicate, listing the offending patch locations.","triggerScenarios":"Two `[patch.crates-io] foo = ...` entries (in the root or different manifests) whose targets both yield `foo 1.2.0`. The `!name_and_version.insert((name, version))` check at registry.rs:463 fails.","commonSituations":"Patching the same crate from both a workspace manifest and a member manifest. Merging patches from multiple sources during a monorepo consolidation. Stale patches left after a dependency was consolidated.","solutions":["Keep only one `[patch]` entry per (package, version) and remove duplicates from other manifests.","If different patches target different versions, ensure their version requirements are disjoint.","Centralize all patches in the workspace root `[patch]` table."],"exampleFix":"# before (root Cargo.toml)\n[patch.crates-io]\nfoo = { git = \"https://example.com/a/foo\" }\n# (and, in a member Cargo.toml)\n[patch.crates-io]\nfoo = { git = \"https://example.com/b/foo\" }\n\n# after (single entry in root)\n[patch.crates-io]\nfoo = { git = \"https://example.com/a/foo\" }","handlingStrategy":"validation","validationCode":"use std::collections::HashSet;\nfn patches_resolve_uniquely(patches: &[(String, semver::Version)]) -> bool {\n    let mut seen = HashSet::new();\n    patches.iter().all(|(n, v)| seen.insert((n.clone(), v.clone())))\n}\n// gather (name, version) for each patch target before resolution","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize `[patch]` entries in the workspace root.","Audit for duplicate patches across member manifests after merges.","Use disjoint version requirements when multiple patches are intentional."],"tags":["cargo","patch","registry","version-resolution","config"],"backgroundTag":null,"analyzedSha":"98a09e7e7d62850f14e5b6132101fc1edd19a16f","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}