rust-lang/cargo · error · anyhow::Error
can't specify both lib and binary outputs
Error message
can't specify both lib and binary outputs
What it means
Returned by NewOptions::new when the caller passes both --bin and --lib simultaneously. A single Cargo package cannot be both a binary-only application crate and a library crate from the new() entrypoint's perspective (the flags are mutually exclusive at the CLI level), so Cargo rejects the contradiction before any files are created.
Source
Thrown at src/ops/cargo_new.rs:116
source_files: Vec<SourceFileInformation>,
edition: Option<&'a str>,
registry: Option<&'a str>,
}
impl NewOptions {
pub fn new(
version_control: Option<VersionControl>,
bin: bool,
lib: bool,
path: PathBuf,
name: Option<String>,
edition: Option<String>,
registry: Option<String>,
) -> CargoResult<NewOptions> {
let auto_detect_kind = !bin && !lib;
let kind = match (bin, lib) {
(true, true) => anyhow::bail!("can't specify both lib and binary outputs"),
(false, true) => NewProjectKind::Lib,
(_, false) => NewProjectKind::Bin,
};
let opts = NewOptions {
version_control,
kind,
auto_detect_kind,
path,
name,
edition,
registry,
};
Ok(opts)
}
}
#[derive(Deserialize)]View on GitHub (pinned to 0e07a15537)
Solutions
- Decide the primary target and pass only one flag: `cargo new --lib myproj` or `cargo new --bin myproj`
- If you genuinely need both a lib and a bin in one package, create it as a lib then manually add src/main.rs plus a [[bin]] target in Cargo.toml
- Drop both flags; Cargo defaults to --bin
Example fix
# before cargo new --bin --lib myproj # after cargo new --lib myproj # then later add src/bin/myproj.rs if a binary is needed
Defensive patterns
Strategy: validation
Validate before calling
fn validate_new_flags(bin: bool, lib: bool) -> Result<(), String> {
if bin && lib {
return Err("pass at most one of --bin/--lib".into());
}
Ok(())
}
validate_new_flags(opts.bin, opts.lib)?; Type guard
type NewKind = 'bin' | 'lib' | 'auto';
function resolveKind(bin: boolean, lib: boolean): NewKind {
if (bin && lib) throw new Error('mutually exclusive');
return bin ? 'bin' : lib ? 'lib' : 'auto';
} Prevention
- Treat --bin/--lib as a single enum (auto|bin|lib) instead of two booleans in wrapper scripts
- In CI, lint cargo invocations that pass both flags
- Document that `cargo new` defaults to --bin so neither flag is usually needed
When it happens
Trigger: Invoking `cargo new --bin --lib myproj` (or the programmatic equivalent NewOptions::new with bin=true and lib=true). The match arm at cargo_new.rs:115-119 catches (true, true).
Common situations: User pastes a cargo invocation assembled from multiple examples and accidentally keeps both flags; shell aliases/scripts that unconditionally add flags; misunderstanding that a crate can contain both src/lib.rs and src/main.rs after creation but `cargo new` only scaffolds one target type.
Related errors
- unknown vcs specification: `{}`
- {err}{help}
- crate name is empty
- dependency name is required
- cannot clean `{}`: {err}
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/aa8d2f9c3efdf1e2.json.
Report an issue: GitHub.