{"record":{"id":"0a896bf0fae96852","repo":"rust-lang/cargo","slug":"found-build-scripts-with-duplicate-file-stems-but","errorCode":null,"errorMessage":"found build scripts with duplicate file stems, but all build scripts must have a unique file stem","messagePattern":"found build scripts with duplicate file stems, but all build scripts must have a unique file stem","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/workspace/parser/targets.rs","lineNumber":928,"sourceCode":"            .file_stem()\n            .and_then(|s| s.to_str())\n            .expect(\"previously normalized\");\n        seen.entry(stem)\n            .or_insert_with(Vec::new)\n            .push(script.as_str());\n    }\n    let mut conflict_file_stem = false;\n    let mut err_msg = String::from(\n        \"found build scripts with duplicate file stems, but all build scripts must have a unique file stem\",\n    );\n    for (stem, paths) in seen {\n        if paths.len() > 1 {\n            conflict_file_stem = true;\n            write!(&mut err_msg, \"\\n  for stem `{stem}`: {}\", paths.join(\", \"))?;\n        }\n    }\n    if conflict_file_stem {\n        anyhow::bail!(err_msg);\n    }\n    Ok(())\n}\n\nfn configure(\n    toml: &TomlTarget,\n    target: &mut Target,\n    target_kind_human: &str,\n    warnings: &mut Vec<String>,\n) -> CargoResult<()> {\n    let t2 = target.clone();\n    target\n        .set_tested(toml.test.unwrap_or_else(|| t2.tested()))\n        .set_doc(toml.doc.unwrap_or_else(|| t2.documented()))\n        .set_doctest(toml.doctest.unwrap_or_else(|| t2.doctested()))\n        .set_benched(toml.bench.unwrap_or_else(|| t2.benched()))\n        .set_harness(toml.harness.unwrap_or_else(|| t2.harness()))\n        .set_proc_macro(toml.proc_macro().unwrap_or_else(|| t2.proc_macro()))","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/rust-lang/cargo/blob/eb98b54bc9f3c74519f43d066cb3fd02ebc88df0/src/workspace/parser/targets.rs#L910-L946","documentation":"When `package.build` lists multiple build scripts (`MultipleScript`), each must have a unique file stem because Cargo derives the generated target name as `build-script-<stem>`. `validate_unique_build_scripts` groups paths by stem and bails if any stem maps to more than one path, listing the offenders.","triggerScenarios":"`[package] build = [\"a/build.rs\", \"b/build.rs\"]` — both files have stem `build`. The `paths.len() > 1` branch at targets.rs:922 flags the stem and bails after building the message.","commonSituations":"Organizing build scripts in subdirectories that share the conventional `build.rs` name. Merging two crates' build steps into one package. Renaming directories but not the script files.","solutions":["Give each build script a distinct file name, e.g. `a/a_build.rs` and `b/b_build.rs`.","Consolidate the logic of duplicate-stem scripts into a single build script.","Re-run `cargo check` to confirm stems are unique."],"exampleFix":"# before\n[package]\nbuild = [\"a/build.rs\", \"b/build.rs\"]\n\n# after\n[package]\nbuild = [\"a/a_build.rs\", \"b/b_build.rs\"]","handlingStrategy":"validation","validationCode":"use std::collections::HashMap;\nfn build_scripts_unique_stems(scripts: &[String]) -> bool {\n    let mut stems: HashMap<String, usize> = HashMap::new();\n    for s in scripts {\n        if let Some(stem) = std::path::Path::new(s).file_stem().and_then(|x| x.to_str()) {\n            *stems.entry(stem.to_string()).or_default() += 1;\n        }\n    }\n    stems.values().all(|c| *c == 1)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Name multi-script builds with distinct stems (e.g. `a_build.rs`).","Avoid placing every script at `<dir>/build.rs`.","Validate stems before committing a multi-script `build` list."],"tags":["cargo","config","build-script","validation","manifest"],"backgroundTag":null,"analyzedSha":"eb98b54bc9f3c74519f43d066cb3fd02ebc88df0","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}