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

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

Error message

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

What it means

Thrown by emit_pattern_not_found (src/ops/cargo_compile/packages.rs:195-214) when one or more glob package patterns (e.g. `pkg-*`) passed via -p / --exclude matched no workspace member. Distinct from error 86: this is specifically for glob patterns that failed to match.

Source

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

            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)
        .map(|(pat, _)| pat.as_str())
        .collect::<Vec<_>>();
    if !not_matched.is_empty() {
        anyhow::bail!(
            "{}package pattern(s) `{}` not found in workspace `{}`",
            if opt_out { "excluded " } else { "" },
            not_matched.join(", "),
            ws.root().display(),
        )
    }
    Ok(())
}

fn emit_packages_not_found_within_workspace(
    ws: &Workspace<'_>,
    packages: &[String],
) -> CargoResult<()> {
    let (mut patterns, mut ids) = opt_patterns_and_ids(packages)?;
    let _: Vec<_> = ws
        .members()
        .filter(|pkg| {
            let id = ids.iter().find(|id| id.matches(pkg.package_id())).cloned();

View on GitHub (pinned to 0e07a15537)

Solutions

  1. List members with `cargo metadata --no-deps` to see actual names and adjust the glob.
  2. Quote the pattern so the shell does not expand it before cargo sees it: `cargo build -p 'foo*'`.
  3. Replace the glob with explicit `-p a -p b` if the set is small.
  4. Verify glob syntax: `*` matches within a path segment, `?` a single char, `[abc]` a set.

Example fix

# before
cargo build -p 'foo-*'     # no member matches

# after
cargo build -p 'foobar'    # use the real member name
Defensive patterns

Strategy: validation

Validate before calling

// Test a glob against member names before passing it to cargo.
fn glob_matches_any(ws: &Workspace, pat: &str) -> bool {
    let Ok(p) = glob::Pattern::new(pat) else { return false };
    ws.members().any(|m| p.matches(m.name().as_str()))
}

Type guard

fn all_globs_match(ws: &Workspace, pats: &[String]) -> bool {
    pats.iter().all(|p| glob_matches_any(ws, p))
}

Try / catch

if let Err(e) = pkgs.get_packages(ws) {
    if e.to_string().contains("pattern(s)") {
        eprintln!("glob matched no member; check syntax and quoting");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: `cargo build -p 'foo*'` where no member matches the glob; `cargo test --workspace --exclude 'x*'` with no excluded match (prefixed 'excluded '). Patterns are split into globs vs exact names; globs that never set their matched flag land in not_matched.

Common situations: Wildcard that no longer matches after a rename/reorg. Glob syntax mistakes (e.g. forgetting the `*`). Patterns authored for a different workspace layout.

Related errors


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