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

cannot have a package with multiple libraries, found both `{

Error message

cannot have a package with multiple libraries, found both `{}` and `{}`

What it means

During `cargo init`, when DetectSourcePaths finds two files that are both classified as library roots (e.g. src/lib.rs AND src/<name>.rs), Cargo refuses because a package can have only one library target. previous_lib_relpath at cargo_new.rs:405 is already set when the second lib file is seen, so it bails naming both paths.

Source

Thrown at src/ops/cargo_new.rs:406

    let mut duplicates_checker: BTreeMap<&str, &SourceFileInformation> = BTreeMap::new();

    for i in detected_files {
        if i.bin {
            if let Some(x) = BTreeMap::get::<str>(&duplicates_checker, &name) {
                anyhow::bail!(
                    "\
multiple possible binary sources found:
  {}
  {}
cannot automatically generate Cargo.toml as the main target would be ambiguous",
                    &x.relative_path,
                    &i.relative_path
                );
            }
            duplicates_checker.insert(name, i);
        } else {
            if let Some(plp) = previous_lib_relpath {
                anyhow::bail!(
                    "cannot have a package with \
                     multiple libraries, \
                     found both `{}` and `{}`",
                    plp,
                    i.relative_path
                )
            }
            previous_lib_relpath = Some(&i.relative_path);
        }
    }

    Ok(())
}

fn plan_new_source_file(bin: bool) -> SourceFileInformation {
    if bin {
        SourceFileInformation {
            relative_path: "src/main.rs".to_string(),

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Keep only one library root (typically src/lib.rs); move or delete the duplicate
  2. If the second file is a module, move it under src/ as a submodule (e.g. src/foo/mod.rs) so it is not mistaken for a crate root
  3. Manually author Cargo.toml with an explicit [lib] section instead of relying on `cargo init` detection

Example fix

# before: src/lib.rs and src/myapp.rs both present
cargo init
# after
mv src/myapp.rs src/myapp/mod.rs   # treat as module
cargo init
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn count_lib_roots(dir: &Path, pkg_name: &str) -> usize {
    let mut n = 0;
    if dir.join("src/lib.rs").is_file() { n += 1; }
    if dir.join(format!("src/{pkg_name}.rs")).is_file() { n += 1; }
    n
}

if count_lib_roots(dir, name) > 1 { /* ask user to keep one */ }

Type guard

import { existsSync } from 'fs';
function hasSingleLibRoot(dir: string, name: string): boolean {
  const a = existsSync(`${dir}/src/lib.rs`);
  const b = existsSync(`${dir}/src/${name}.rs`);
  return !(a && b);
}

Prevention

When it happens

Trigger: Run `cargo init` in a directory containing both `src/lib.rs` and `src/<pkgname>.rs` (the per-name lib candidate), or two files that do not contain `fn main` and are thus detected as libraries.

Common situations: Pre-existing source tree with a src/lib.rs plus a sibling module file at src/<crate>.rs that Cargo's heuristic interprets as another lib; migration of a project that uses the 2015-era module layout; leftover stub files.

Related errors


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