rust-lang/cargo · error
` ` was defined in but could not be resolved with
Error message
`{}` was defined in {} but could not be resolved with {} What it means
`resolve_relative_path` takes a label, an old root, a new root, and a relative path. It joins `old_root` + `rel_path`, normalizes it, then calls `diff_paths(joined, new_root)` to express that path relative to `new_root`. `diff_paths` returns `None` when the two paths do not share a common ancestor (e.g. different drive letters on Windows, or a path that cannot be made relative to the target). In that case the function errors out, naming the label, the old root, and the new root.
Solutions
- Ensure both `old_root` and `new_root` live on the same drive/volume so `diff_paths` can compute a relative path.
- Use an absolute path for the relocated resource instead of relying on relativization across volumes.
- If you control the invocation, pass roots that share a common prefix (same drive letter on Windows, same mount on Unix).
Example fix
// before: roots on different drives (Windows)
resolve_relative_path("pkg", Path::new("C:\\ws"), Path::new("D:\\out"), "pkg/Cargo.toml")
// -> Err("`pkg` was defined in C:\\ws but could not be resolved with D:\\out")
// after: same drive
resolve_relative_path("pkg", Path::new("C:\\ws"), Path::new("C:\\out"), "pkg/Cargo.toml") Defensive patterns
Strategy: validation
Validate before calling
use std::path::{Path, Component};
use same_file::Handle; // or compare components
fn same_volume(a: &Path, b: &Path) -> bool {
// On Windows compare Prefix components; on Unix assume single root unless absolute differ
matches!(
(a.components().next(), b.components().next()),
(Some(Component::RootDir), Some(Component::RootDir))
)
}
// ensure old_root and new_root share a volume before calling resolve_relative_path Prevention
- Keep workspace relocation targets on the same drive/volume.
- Prefer absolute paths when crossing volumes is unavoidable.
- On Windows, normalize drive letters before relativization.
When it happens
Trigger: Calling `resolve_relative_path` where `old_root.join(rel_path)` cannot be relativized against `new_root` — most commonly on Windows when the roots are on different drives (e.g. `C:\ws` vs `D:\out`), or when one path is absolute on a different volume than the other.
Common situations: Workspace relocation across volumes (building on a different drive), moving a workspace to a tmpdir on a separate mount, or invoking Cargo with `--remap-path-prefix`-style root changes that cross filesystem boundaries.
Related errors
- the path was not found
- can only edit absolute paths, got
- cannot override `workspace.lints` in `lints`, either remove…
- failed to find a workspace root
- ` .workspace = false` is unsupported
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/f7001fc9d783f130.
Report an issue: GitHub.
Appendix: source
Thrown at src/workspace/workspace.rs:2087
.map(|p| p.with_context(|| format!("unable to match path to pattern `{}`", &path)))
.collect::<Result<Vec<_>, _>>()?;
Ok(res)
}
pub fn inheritable(&self) -> &InheritableFields {
&self.inheritable_fields
}
}
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 98a09e7e7d)