{"id":"bf8e6e8a4c1c9f8a","repo":"rust-lang/cargo","slug":"found-duplicate-binary-artifact","errorCode":null,"errorMessage":"Found {} duplicate binary artifact{}","messagePattern":"Found (.+?) duplicate binary artifact(.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/workspace/dependency.rs","lineNumber":675,"sourceCode":"        })\n    }\n\n    fn validate(kinds: Vec<ArtifactKind>) -> CargoResult<Vec<ArtifactKind>> {\n        if kinds.iter().any(|k| matches!(k, ArtifactKind::AllBinaries))\n            && kinds\n                .iter()\n                .any(|k| matches!(k, ArtifactKind::SelectedBinary(_)))\n        {\n            anyhow::bail!(\n                \"Cannot specify both 'bin' and 'bin:<name>' binary artifacts, as 'bin' selects all available binaries.\"\n            );\n        }\n        let mut kinds_without_dupes = kinds.clone();\n        kinds_without_dupes.sort();\n        kinds_without_dupes.dedup();\n        let num_dupes = kinds.len() - kinds_without_dupes.len();\n        if num_dupes != 0 {\n            anyhow::bail!(\n                \"Found {} duplicate binary artifact{}\",\n                num_dupes,\n                (num_dupes > 1).then(|| \"s\").unwrap_or(\"\")\n            );\n        }\n        Ok(kinds)\n    }\n}\n\n/// Patch is a dependency override that knows where it has been defined.\n/// See [`PatchLocation`] for possible locations.\n#[derive(Clone, Debug)]\npub struct Patch {\n    pub dep: Dependency,\n    pub loc: PatchLocation,\n}\n\n/// Place where a [`Patch`] has been defined.","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/workspace/dependency.rs#L657-L693","documentation":"Thrown by `ArtifactKind::validate` in src/workspace/dependency.rs:675 when parsing the `--artifact` CLI flags. Cargo collects every artifact specifier (e.g. `bin`, `bin:foo`, `cdylib`, `staticlib`), sorts and dedups them, and bails if any specifier appears more than once, because duplicates are redundant and would produce ambiguous build output.","triggerScenarios":"Calling `cargo build --artifact bin:foo --artifact bin:foo`, `--artifact cdylib --artifact cdylib`, or `cargo build --artifact bin:foo --artifact bin:foo --artifact bin:foo` (produces count 2, pluralized \"artifact{}\"). The check runs in `Artifact::parse` which maps each `--artifact` value through `ArtifactKind::parse` then `ArtifactKind::validate`.","commonSituations":"Shell loops or scripts that append duplicate `--artifact` flags; copy-paste of build commands; build-system wrappers that fan out artifact lists without de-duplicating; CI matrices that concat artifact specs.","solutions":["De-duplicate the `--artifact` values before passing them to cargo: `printf '%s\\n' \"${ARTIFACTS[@]}\" | sort -u | xargs -I{} cargo build --artifact {}`.","Inspect your build script/generator and remove the repeated `--artifact <same>` entry.","Run `cargo build --artifact bin --artifact cdylib` with each kind only once; note `bin` already covers all binaries so never combine `bin` with `bin:<name>` (that is a separate error)."],"exampleFix":"// before\ncargo build --artifact bin:foo --artifact bin:foo\n// after\ncargo build --artifact bin:foo","handlingStrategy":"validation","validationCode":"use std::collections::BTreeSet;\nlet mut seen = BTreeSet::new();\nlet mut deduped = Vec::new();\nfor a in artifacts {\n    if seen.insert(a.as_ref().to_string()) {\n        deduped.push(a);\n    }\n}\n// pass `deduped` to cargo / Artifact::parse","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate `--artifact` lists from a de-duplicated set, never a raw array.","Never combine bare `bin` with `bin:<name>` (separate error) when building artifact lists.","Unit-test your build-command builder to assert no duplicate specifiers."],"tags":["cli","build-artifacts","validation"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}