rust-lang/cargo · error
library target names cannot contain hyphens
Error message
library target names cannot contain hyphens: {} What it means
A library target's explicit `name` (the `[lib] name` field, not the package name) cannot contain hyphens, because it maps to a Rust crate identifier and module path. Cargo would normally derive the underscore form from the package name, but an explicit hyphenated lib name is rejected at targets.rs:1157-1159.
Solutions
- Replace hyphens with underscores: `name = "my_lib"`.
- Omit the `[lib] name` field to let Cargo derive it from the package name automatically.
- Keep the package name hyphenated; only the lib `name` must use underscores.
Example fix
# before [lib] name = "my-lib" # after [lib] name = "my_lib"
Defensive patterns
Strategy: validation
Validate before calling
fn lib_name_valid(name: &str) -> bool {
!name.contains('-')
}
// enforce underscores for explicit `[lib] name` values Prevention
- Use underscores in `[lib] name`; hyphens are fine only in `[package] name`.
- Omit `[lib] name` to let Cargo derive the underscore form.
- Remember package name and lib crate name are distinct concepts.
When it happens
Trigger: Cargo.toml has `[lib] name = "my-lib"`. The `name.contains('-')` check fires.
Common situations: Setting `[lib] name` to match a hyphenated package name verbatim. Renaming a lib target without converting hyphens. Confusing the package name (hyphens allowed) with the lib crate name (underscores only).
Related errors
- can't find library ` `, rename file to `src/lib.rs` or…
- cannot mix `proc-macro` crate type with others
- cannot specify both `metabuild` and `build`
- found build scripts with duplicate file stems, but all…
- found duplicate name , but all targets must have a unique…
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/4400322375732fed.
Report an issue: GitHub.
Appendix: source
Thrown at src/workspace/parser/targets.rs:1152
fn validate_build_name(build: &str) -> CargoResult<()> {
if Path::new(build).file_stem().is_none() {
anyhow::bail!("invalid `package.build` file name");
}
Ok(())
}
fn name_or_panic(target: &TomlTarget) -> &str {
target
.name
.as_deref()
.unwrap_or_else(|| panic!("target name is required"))
}
fn validate_lib_name(target: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
validate_target_name(target, TARGET_KIND_HUMAN_LIB, TARGET_KIND_LIB, warnings)?;
let name = name_or_panic(target);
if name.contains('-') {
anyhow::bail!("library target names cannot contain hyphens: {}", name)
}
Ok(())
}
fn validate_bin_name(bin: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
validate_target_name(bin, TARGET_KIND_HUMAN_BIN, TARGET_KIND_BIN, warnings)?;
let name = name_or_panic(bin).to_owned();
if restricted_names::is_conflicting_artifact_name(&name) {
anyhow::bail!(
"the binary target name `{name}` is forbidden, \
it conflicts with cargo's build directory names",
)
}
Ok(())
}
View on GitHub (pinned to eb98b54bc9)