rust-lang/cargo · error
patch for ` ` in ` ` resolved to more than one…
Error message
patch for `{}` in `{}` resolved to more than one candidate
note: found versions: {}
help: check `{}` patch definition for `{}` in `{}`
help: select only one package using `version = "={}"` What it means
A `[patch]` entry matched more than one candidate version in the target source. Cargo requires a patch to resolve to exactly one package; multiple matches are ambiguous. The registry collects all matched summaries, and if `summaries.len() > 1` it sorts them and bails, suggesting the user pin with `version = "=<highest>"`.
Solutions
- Add a `version` requirement to the patch to select one candidate, e.g. `version = "=1.1.0"`.
- Point the patch at a git rev/tag that contains only the desired version.
- Use a path patch to a checkout holding a single version.
Example fix
# before
[patch.crates-io]
foo = { git = "https://example.com/foo-fork" }
# after
[patch.crates-io]
foo = { git = "https://example.com/foo-fork", version = "=1.1.0" } Defensive patterns
Strategy: validation
Validate before calling
// Pre-check: a patch should select exactly one candidate version
fn patch_has_single_candidate(available: &[semver::Version], req: &semver::VersionReq) -> bool {
available.iter().filter(|v| req.matches(v)).count() == 1
} Prevention
- Add a `version` requirement (ideally `="X.Y.Z"`) to every patch entry.
- Pin patches to a specific git rev/tag.
- Re-check patches after the fork gains new versions.
When it happens
Trigger: `[patch.crates-io] foo = { git = "https://..." }` where the git repo publishes multiple versions of `foo` (e.g. 1.0.0 and 1.1.0) with no version constraint to disambiguate.
Common situations: Patching to a fork or monorepo that contains several versions of the crate. Forgetting the `version` key in a patch entry. Upstream repo gaining new versions after the patch was written.
Related errors
- patch ` ` version mismatch note: patch location contains …
- several `[patch]` entries resolving to same version
- found patches and a path override
- patch for ` ` points to the same source, but patches must…
- patch location ` ` does not contain packages matching `…
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/24a764135e223c78.
Report an issue: GitHub.
Appendix: source
Thrown at src/workspace/registry.rs:980
locked: &Option<LockedPatchDependency>,
mut summaries: Vec<Summary>,
source: &dyn Source,
) -> CargoResult<(Summary, Option<PackageId>)> {
if summaries.len() == 1 {
return Ok((summaries.pop().unwrap(), None));
}
if summaries.len() > 1 {
// TODO: In the future, it might be nice to add all of these
// candidates so that version selection would just pick the
// appropriate one. However, as this is currently structured, if we
// added these all as patches, the unselected versions would end up in
// the "unused patch" listing, and trigger a warning. It might take a
// fair bit of restructuring to make that work cleanly, and there
// isn't any demand at this time to support that.
let mut vers: Vec<_> = summaries.iter().map(|summary| summary.version()).collect();
vers.sort();
let versions: Vec<_> = vers.into_iter().map(|v| v.to_string()).collect();
return Err(anyhow::anyhow!(
"patch for `{}` in `{}` resolved to more than one candidate\n\
note: found versions: {}\n\
help: check `{}` patch definition for `{}` in `{}`\n\
help: select only one package using `version = \"={}\"`",
&original_patch.dep.package_name(),
&original_patch.dep.source_id(),
versions.join(", "),
&original_patch.dep.package_name(),
orig_patch_url,
original_patch.loc,
versions.last().unwrap()
));
}
assert!(summaries.is_empty());
// No summaries found, try to help the user figure out what is wrong.
if let Some(locked) = locked {
// Since the locked patch did not match anything, try the unlocked one.
let orig_matches = sourceView on GitHub (pinned to 98a09e7e7d)