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

dependency ({}) specified without providing a local path, Gi

Error message

dependency ({}) specified without providing a local path, Git repository, or version

What it means

During registry lookup, `query_dependency` recurses into workspace inheritance: if a dependency resolves to `MaybeWorkspace::Workspace`, cargo looks it up in `[workspace.dependencies]`. Should that *also* come back as `Workspace` (i.e. the workspace dep has no concrete source itself), the resolver bails at mod.rs:654 because there is no local path, git, or version to anchor the dependency.

Source

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

    gctx: &GlobalContext,
    dependency: &mut Dependency,
) -> CargoResult<crate::workspace::Dependency> {
    let query = dependency.query(gctx)?;
    let query = match query {
        MaybeWorkspace::Workspace(_workspace) => {
            let dep = find_workspace_dep(
                dependency.toml_key(),
                ws,
                ws.root_manifest(),
                ws.unstable_features(),
            )?;
            if let Some(features) = dep.features.clone() {
                *dependency = dependency.clone().set_inherited_features(features);
            }
            let query = dep.query(gctx)?;
            match query {
                MaybeWorkspace::Workspace(_) => {
                    anyhow::bail!(
                        "dependency ({}) specified without \
                        providing a local path, Git repository, or version",
                        dependency.toml_key()
                    );
                }
                MaybeWorkspace::Other(query) => query,
            }
        }
        MaybeWorkspace::Other(query) => query,
    };
    Ok(query)
}

fn fuzzy_lookup(
    dependency: &mut Dependency,
    lookup: impl Fn(&str) -> CargoResult<Option<Dependency>>,
    gctx: &GlobalContext,
) -> CargoResult<Option<Dependency>> {

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Give the `[workspace.dependencies.<key>]` entry a concrete `version`, `path`, or `git`.
  2. If the member needs its own source, declare it directly in the member manifest instead of inheriting an empty workspace entry.
  3. Audit the workspace root `Cargo.toml` for entries that only set `workspace = true` and supply them with a real source.

Example fix

# before (root Cargo.toml)
[workspace.dependencies]
serde = { workspace = true }

# after
[workspace.dependencies]
serde = "1"
Defensive patterns

Strategy: validation

Validate before calling

// Validate workspace.dependencies entries have a concrete source before adding members.
fn ws_deps_are_concrete(root_manifest: &toml_edit::DocumentMut) -> Result<(), Vec<String>> {
    let mut bad = Vec::new();
    if let Some(t) = root_manifest.get("workspace").and_then(|i| i.as_table()) {
        if let Some(deps) = t.get("dependencies").and_then(|i| i.as_table_like()) {
            for (k, v) in deps.iter() {
                let only_ws = v.as_table_like()
                    .map(|tt| tt.contains_key("workspace") && tt.len() == 1)
                    .unwrap_or(false);
                if only_ws { bad.push(k.to_string()); }
            }
        }
    }
    if bad.is_empty() { Ok(()) } else { Err(bad) }
}

Prevention

When it happens

Trigger: A `[workspace.dependencies]` entry declared as `{ workspace = true }` (transitive/forwarding) with no version/path/git, and a member references it. The double-Workspace resolution has no concrete source to query.

Common situations: Mistakenly nesting workspace dependencies, or refactoring a workspace dep into a stub that never gets a real source assigned.

Related errors


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