rust-lang/cargo · error
std has a lib
Error message
std has a lib
What it means
While generating std root units, `generate_std_roots` finds each package's library target via `.find(|t| t.is_lib()).expect("std has a lib")`. Every std-workspace crate that Cargo asks to build is expected to expose a `lib` target. The panic means a requested std crate has no library target — it was asked for by name but contributes only a bin/example/etc.
Source
Thrown at src/compiler/standard_lib.rs:182
std_features: &ResolvedFeatures,
kinds: &[&CompileKind],
package_set: &PackageSet<'_>,
interner: &UnitInterner,
profiles: &Profiles,
target_data: &RustcTargetData<'_>,
) -> CargoResult<()> {
let std_ids = std_crates(crates, default, units)
.iter()
.map(|crate_name| std_resolve.query(crate_name))
.collect::<CargoResult<Vec<PackageId>>>()?;
let std_pkgs = package_set.get_many(std_ids)?;
for pkg in std_pkgs {
let lib = pkg
.targets()
.iter()
.find(|t| t.is_lib())
.expect("std has a lib");
// I don't think we need to bother with Check here, the difference
// in time is minimal, and the difference in caching is
// significant.
let mode = CompileMode::Build;
let features = std_features.activated_features(pkg.package_id(), FeaturesFor::NormalOrDev);
for kind in kinds {
let kind = **kind;
let list = ret.entry(kind).or_insert_with(Vec::new);
let unit_for = UnitFor::new_normal(kind);
let profile = profiles.get_profile(
pkg.package_id(),
/*is_member*/ false,
/*is_local*/ false,
unit_for,
kind,
);
list.push(interner.intern(
pkg,View on GitHub (pinned to 0e07a15537)
Solutions
- Restrict `-Zbuild-std` to library crates of the std workspace (typically `std`, `core`, `alloc`, `proc_macro`, `panic_abort`, `panic_unwind`, `compiler_builtins`).
- `rustup component add rust-src` and use the matching nightly Cargo.
- If you maintain a patched rust-src, ensure each requested crate has a `[lib]` target.
Example fix
// before
let lib = pkg
.targets()
.iter()
.find(|t| t.is_lib())
.expect("std has a lib");
// after
let lib = pkg
.targets()
.iter()
.find(|t| t.is_lib())
.ok_or_else(|| anyhow::anyhow!("std crate `{}` has no lib target", pkg.package_id()))?; Defensive patterns
Strategy: validation
Validate before calling
// Confirm each requested -Zbuild-std crate has a lib target in the std source tree
fn crate_has_lib(std_src: &std::path::Path, name: &str) -> bool {
std::fs::read_to_string(std_src.join(name).join("Cargo.toml"))
.map(|t| t.contains("[lib]") || !t.contains("[[bin]]"))
.unwrap_or(false)
} Prevention
- Restrict `-Zbuild-std` to library crates of the std workspace.
- Use matching nightly Cargo + `rustup component add rust-src`.
- If patching rust-src, ensure every requested crate defines a `[lib]`.
When it happens
Trigger: Passing `-Zbuild-std=<name>` where `<name>` is a std-workspace crate without a lib target (e.g. a tools/binary crate), or a rust-src layout where the `Cargo.toml` lacks a `[lib]`/auto-detected lib; a Cargo/std-source version mismatch where a crate's target set changed.
Common situations: Hand-tuning `-Zbuild-std` to include non-library crates; pointing `__CARGO_TESTS_ONLY_SRC_ROOT` at a modified std source tree; mismatched rust-src and Cargo expectations on nightly.
Related errors
- resolve should have a single spec with resolved features
- able to invoke rustc
- required(true)
- a file should always have a parent
- already loaded without errors
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/85f48d03586947e9.json.
Report an issue: GitHub.