rust-lang/cargo · error · anyhow::Error
--exclude can only be used together with --workspace
Error message
--exclude can only be used together with --workspace
What it means
Thrown by Packages::from_flags when an --exclude list is supplied but the `all` (i.e. --workspace) flag is false. Exclusion is only meaningful across the whole workspace, so cargo rejects it in any other selection mode.
Solutions
- Add --workspace (or --all) alongside --exclude.
- If you meant to exclude by default, restructure workspace `default-members` instead.
- Use -p with explicit members rather than --exclude if you do not want --workspace.
Example fix
# before cargo build --exclude foo # after cargo build --workspace --exclude foo
Defensive patterns
Strategy: validation
Validate before calling
// Validate flag combination before calling Packages::from_flags.
fn valid(exclude: &[String], all: bool) -> bool { exclude.is_empty() || all } Prevention
- Always pass --workspace when using --exclude.
- In wrappers, reject --exclude unless --workspace is also set.
- Use `default-members` for persistent filtering instead of --exclude on every command.
When it happens
Trigger: Running `cargo build --exclude foo` without also passing --workspace (or its aliases -all). Also via programmatic Packages::from_flags(false, non_empty, n).
Common situations: Cargo CLI invocations / scripts that add --exclude expecting it to filter default members; wrappers that pass exclude unconditionally.
Related errors
- package pattern(s) ` ` not found in workspace
- package(s) ` ` not found in workspace
- extra arguments to ` ` can only be passed to one target…
- no library targets found in packages
- no target
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/68bdb80e697553ec.
Report an issue: GitHub.
Appendix: source
Thrown at src/ops/cargo_compile/packages.rs:39
///
/// As of the time of this writing, it only works on opting in all workspace members.
/// Keeps the packages passed in to verify that they exist in the workspace.
All(Vec<String>),
/// Opt out of packages passed in.
///
/// As of the time of this writing, it only works on opting out workspace members.
OptOut(Vec<String>),
/// A sequence of hand-picked packages that will be built. Normally done by `-p` flag.
Packages(Vec<String>),
}
impl Packages {
/// Creates a `Packages` from flags which are generally equivalent to command line flags.
pub fn from_flags(all: bool, exclude: Vec<String>, package: Vec<String>) -> CargoResult<Self> {
Ok(match (all, exclude.len(), package.len()) {
(false, 0, 0) => Packages::Default,
(false, 0, _) => Packages::Packages(package),
(false, _, _) => anyhow::bail!("--exclude can only be used together with --workspace"),
(true, 0, _) => Packages::All(package),
(true, _, _) => Packages::OptOut(exclude),
})
}
/// Converts selected packages to [`PackageIdSpec`]s.
pub fn to_package_id_specs(&self, ws: &Workspace<'_>) -> CargoResult<Vec<PackageIdSpec>> {
let specs = match self {
Packages::All(packages) => {
emit_packages_not_found_within_workspace(ws, packages)?;
ws.members()
.map(Package::package_id)
.map(|id| id.to_spec())
.collect()
}
Packages::OptOut(opt_out) => {
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_out)?;
let specs = wsView on GitHub (pinned to eb98b54bc9)