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

{}package(s) `{}` not found in workspace `{}`

Error message

{}package(s) `{}` not found in workspace `{}`

What it means

Thrown by emit_package_not_found (src/ops/cargo_compile/packages.rs:178-192) when one or more exact package-name specs passed via -p / --exclude do not match any workspace member (or, with the prefix, any excluded member). The names that failed to match are listed.

Source

Thrown at src/ops/cargo_compile/packages.rs:184

    /// specific package in the workspace.
    pub fn needs_spec_flag(&self, ws: &Workspace<'_>) -> bool {
        match self {
            Packages::Default => ws.default_members().count() > 1,
            Packages::All(_) => ws.members().count() > 1,
            Packages::Packages(_) => true,
            Packages::OptOut(_) => true,
        }
    }
}

/// Emits "package not found" error.
fn emit_package_not_found(
    ws: &Workspace<'_>,
    opt_names: BTreeSet<String>,
    opt_out: bool,
) -> CargoResult<()> {
    if !opt_names.is_empty() {
        anyhow::bail!(
            "{}package(s) `{}` not found in workspace `{}`",
            if opt_out { "excluded " } else { "" },
            opt_names.into_iter().collect::<Vec<_>>().join(", "),
            ws.root().display(),
        )
    }
    Ok(())
}

/// Emits "glob pattern not found" error.
fn emit_pattern_not_found(
    ws: &Workspace<'_>,
    opt_patterns: Vec<(glob::Pattern, bool)>,
    opt_out: bool,
) -> CargoResult<()> {
    let not_matched = opt_patterns
        .iter()
        .filter(|(_, matched)| !*matched)

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Run `cargo metadata --no-deps` (or `ls` the workspace) to list the exact member names and correct the spelling.
  2. Update the -p / --exclude argument to the real crate name (note: use the package name, not the path).
  3. If the crate was removed, delete the now-invalid reference from scripts/CI.
  4. Use a glob pattern only if you intended a pattern; otherwise exact names must match.

Example fix

# before
cargo build -p mycrate-typo

# after
cargo build -p mycrate
Defensive patterns

Strategy: validation

Validate before calling

// Verify each exact -p / --exclude name is a workspace member.
fn known_members(ws: &Workspace) -> std::collections::HashSet<String> {
    ws.members().map(|m| m.name().as_str().to_string()).collect()
}
// let members = known_members(ws);
// for n in &specs { assert!(members.contains(n), "unknown package {}", n); }

Type guard

fn all_names_are_members(ws: &Workspace, names: &[String]) -> bool {
    let members: std::collections::HashSet<_> =
        ws.members().map(|m| m.name().as_str().to_string()).collect();
    names.iter().all(|n| members.contains(n))
}

Try / catch

if let Err(e) = pkgs.get_packages(ws) {
    if e.to_string().contains("not found in workspace") {
        eprintln!("run `cargo metadata --no-deps` to list valid member names");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: `cargo build -p typo-name`, `cargo test --workspace --exclude ghost` (prefixes the message with 'excluded '), or any Packages selection where an exact PackageIdSpec does not resolve to a workspace member. The remaining opt_names set is non-empty at bail time.

Common situations: Typos in package names. Renaming a crate without updating CI scripts. Referring to a dependency by its source name rather than the workspace member name. Stale references after a crate was removed from the workspace.

Related errors


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