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

crate types to rustc can only be passed to one target, consi

Error message

crate types to rustc can only be passed to one target, consider filtering
the package by passing, e.g., `--lib` or `--example` to specify a single target

What it means

Thrown by override_rustc_crate_types (src/ops/cargo_compile/mod.rs:1145-1156) when `cargo rustc --crate-type <TYPES>` resolves to a number of units other than 1. Crate-type overrides mutate a single target, so Cargo requires exactly one target selected.

Source

Thrown at src/ops/cargo_compile/mod.rs:1151

            visit(&dep.unit, graph, visited);
        }
    }
    for unit in root_units {
        visit(unit, unit_graph, &mut visited);
    }
    unit_graph.retain(|unit, _| visited.contains(unit));
}

/// Override crate types for given units.
///
/// This is primarily used by `cargo rustc --crate-type`.
fn override_rustc_crate_types(
    units: &mut [Unit],
    args: &[String],
    interner: &UnitInterner,
) -> CargoResult<()> {
    if units.len() != 1 {
        anyhow::bail!(
            "crate types to rustc can only be passed to one \
            target, consider filtering\nthe package by passing, \
            e.g., `--lib` or `--example` to specify a single target"
        );
    }

    let unit = &units[0];
    let override_unit = |f: fn(Vec<CrateType>) -> TargetKind| {
        let crate_types = args.iter().map(|s| s.into()).collect();
        let mut target = unit.target.clone();
        target.set_kind(f(crate_types));
        interner.intern(
            &unit.pkg,
            &target,
            unit.profile.clone(),
            unit.kind,
            unit.mode,
            unit.features.clone(),

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Add a single-target filter such as `--lib`, `--example NAME`, or `-p <pkg> --lib`.
  2. Ensure only one library/example-library unit matches (the only kinds --crate-type can apply to).
  3. Remove --crate-type if you did not intend to override crate types.

Example fix

# before
cargo rustc --crate-type cdylib         # multiple units

# after
cargo rustc -p mycrate --lib --crate-type cdylib
Defensive patterns

Strategy: validation

Validate before calling

// Before override_rustc_crate_types, ensure one unit is selected.
fn ensure_single_unit(units: &[Unit]) -> Result<&Unit, String> {
    match units {
        [u] => Ok(u),
        _ => Err("pass --lib or --example to select exactly one target".into()),
    }
}

Type guard

fn is_single_lib_or_example(units: &[Unit]) -> bool {
    units.len() == 1 && matches!(
        units[0].target.kind(),
        cargo::core::TargetKind::Lib(_) | cargo::core::TargetKind::ExampleLib(_)
    )
}

Try / catch

if let Err(e) = ops::compile(ws, &opts) {
    if e.to_string().contains("crate types to rustc can only be passed") {
        eprintln!("narrow to a single lib/example target with --lib or --example");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Running `cargo rustc --crate-type cdylib` (or --crate-type with multiple values) when the current selection produces more than one unit — e.g. default workspace with multiple crates, or a package with several libs/examples. The `units.len() != 1` check fires.

Common situations: Trying to produce a cdylib from a workspace root without -p. Mixing --crate-type with --all or default multi-target selection. Scripting artifact builds without narrowing the target.

Related errors


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