rust-lang/cargo · error · anyhow::Error
`{}` was defined in {} but could not be resolved with {}
Error message
`{}` was defined in {} but could not be resolved with {} What it means
Returned by `resolve_relative_path` (src/workspace/registry.rs is wrong — actual: src/workspace/workspace.rs:2142) when `diff_paths(joined_path, new_root)` returns `None`, meaning the path formed by joining `old_root` + `rel_path` does not lie underneath `new_root`. Cargo cannot express a relative path between the two trees, so it errors naming the label, where it was defined, and the target root it failed to resolve against.
Source
Thrown at src/workspace/workspace.rs:2142
"ignoring `registries.{name}.min-publish-age` without `-Zmin-publish-age`"
))?;
}
}
}
}
Ok(())
}
pub fn resolve_relative_path(
label: &str,
old_root: &Path,
new_root: &Path,
rel_path: &str,
) -> CargoResult<String> {
let joined_path = normalize_path(&old_root.join(rel_path));
match diff_paths(joined_path, new_root) {
None => Err(anyhow!(
"`{}` was defined in {} but could not be resolved with {}",
label,
old_root.display(),
new_root.display()
)),
Some(path) => Ok(path
.to_str()
.ok_or_else(|| {
anyhow!(
"`{}` resolved to non-UTF value (`{}`)",
label,
path.display()
)
})?
.to_owned()),
}
}
View on GitHub (pinned to 0e07a15537)
Solutions
- Verify `rel_path` (with `..`) still resolves under `new_root` after the move; adjust the manifest path to point inside the new root.
- Ensure `old_root` and `new_root` are both absolute and canonicalized before calling.
- If the path legitimately lives outside the new root, switch the manifest to an absolute path or a registry/git dependency instead of a relative one.
Example fix
// before
let p = resolve_relative_path("dep", &old_root, &new_root, "../../outside/dep")?;
// after — move dep under new_root and reference relatively
let p = resolve_relative_path("dep", &old_root, &new_root, "members/dep")?; Defensive patterns
Strategy: validation
Validate before calling
use std::path::{Path, Component};
fn is_under(new_root: &Path, joined: &Path) -> bool {
let joined = std::fs::canonicalize(joined).unwrap_or_else(|_| joined.to_path_buf());
let new_root = std::fs::canonicalize(new_root).unwrap_or_else(|_| new_root.to_path_buf());
joined.starts_with(new_root)
}
// before calling resolve_relative_path, assert is_under(&new_root, &old_root.join(rel_path)) Try / catch
// best-effort: fall back to an absolute path string
let p = resolve_relative_path(label, &old_root, &new_root, rel)
.unwrap_or_else(|_| old_root.join(rel).to_string_lossy().into_owned()); Prevention
- Keep patched/path dependencies inside the workspace root.
- Canonicalize both roots before computing relative paths.
- Avoid `..` escapes in dependency paths.
When it happens
Trigger: Calling `resolve_relative_path(label, old_root, new_root, rel_path)` where `old_root.join(rel_path)` canonicalizes outside of `new_root` — e.g. the relative path escapes via `..` components, or `new_root` is not an ancestor of the joined path.
Common situations: Workspace relocation where a patch/path dependency referenced by a relative `..` no longer sits under the new workspace root; publishing or packaging with a rewritten root; symlinks causing `diff_paths` to disagree about ancestry.
Related errors
- no executable for `{}` found in PATH
- `{feature}` is unsupported when inferring the crate name, us
- package `{}` cannot be tested because it requires dev-depend
- --exclude can only be used together with --workspace
- {}package(s) `{}` not found in workspace `{}`
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/f7001fc9d783f130.json.
Report an issue: GitHub.