rust-lang/cargo · error · anyhow::Error

cannot specify a path (`{raw_path}`) with a version (`{v}`).

Error message

cannot specify a path (`{raw_path}`) with a version (`{v}`).

What it means

Symmetric to the git case: a path source cannot be combined with an inline version requirement. When `--path <p>` is given and the crate spec contains a version (`x@1.0`), cargo-add bails at mod.rs:408 because a path dependency's version comes from the local manifest at that path, not a registry requirement.

Source

Thrown at src/ops/cargo_add/mod.rs:408

        let path = paths::normalize_path(&std::env::current_dir()?.join(raw_path));
        let mut src = PathSource::new(path);
        src.base = arg.base.clone();

        if let Some(base) = &arg.base {
            // Validate that the base is valid.
            let workspace_root = || Ok(ws.root_manifest().parent().unwrap());
            lookup_path_base(
                &PathBaseName::new(base.clone())?,
                &gctx,
                &workspace_root,
                spec.manifest().unstable_features(),
            )?;
        }

        let selected = if let Some(crate_spec) = &crate_spec {
            if let Some(v) = crate_spec.version_req() {
                // crate specifier includes a version (e.g. `docopt@0.8`)
                anyhow::bail!("cannot specify a path (`{raw_path}`) with a version (`{v}`).");
            }
            let dependency = crate_spec.to_dependency()?.set_source(src);
            let selected = select_package(&dependency, gctx, registry)?;
            if dependency.name != selected.name {
                gctx.shell().warn(format!(
                    "translating `{}` to `{}`",
                    dependency.name, selected.name,
                ))?;
            }
            selected
        } else {
            let source = crate::sources::PathSource::new(&src.path, src.source_id()?, gctx);
            let package = source.root_package()?;
            let mut selected = Dependency::from(package.summary());
            if let Some(Source::Path(selected_src)) = &mut selected.source {
                selected_src.base = src.base;
            }
            selected

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Drop the `@version`: `cargo add --path <dir> <crate>` and let the path crate's own version apply.
  2. If you must pin the path crate, set `version = "..."` directly in the path crate's `Cargo.toml`, not on the `cargo add` line.
  3. If a version requirement is truly required, you need a registry/git source rather than `--path`.

Example fix

# before
cargo add --path ../libs/foo mycrate@1.0

# after
cargo add --path ../libs/foo mycrate
Defensive patterns

Strategy: validation

Validate before calling

// A path source cannot carry a version req; reject it up front.
fn build_path_dep_op(name: &str, path: &str, ver: Option<&str>) -> Result<DepOp, String> {
    if ver.is_some() {
        return Err("cannot combine --path with a version requirement".into());
    }
    Ok(DepOp { crate_spec: Some(name.into()), path: Some(path.into()), ..Default::default() })
}

Prevention

When it happens

Trigger: `cargo add --path ../libs/foo mycrate@1.0` triggers it; `--path` plus a `crate_spec` with a non-empty `version_req()` is the exact condition.

Common situations: Workspace-local path crates where the user reflexively adds a version pin, or scripts that build specs uniformly as `name@version` regardless of source kind.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/560ce7af0134b794.json. Report an issue: GitHub.