{"record":{"id":"0b52752df117cfef","repo":"zeroclaw-labs/zeroclaw","slug":"cli-skills-multiple-locations-path","errorCode":"cli-skills-multiple-locations-path","errorMessage":"skill '{$name}' exists in multiple locations ({$locations}); pass an explicit path to disambiguate","messagePattern":"skill '(.+?)' exists in multiple locations \\((.+?)\\); pass an explicit path to disambiguate","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/skills/mod.rs","lineNumber":698,"sourceCode":"        }\n    }\n    out\n}\n\n/// Locate a single installed skill directory by name (across bundles + global),\n/// erroring when absent or ambiguous. Used by `audit`/`test`.\nfn locate_installed_skill_dir(config: &crate::config::Config, name: &str) -> Result<PathBuf> {\n    let mut matches = collect_skill_locations(config, name, None);\n    match matches.len() {\n        0 => anyhow::bail!(\"Skill not found: {name}\"),\n        1 => Ok(matches.remove(0).1),\n        _ => {\n            let locs = matches\n                .iter()\n                .map(|(label, _)| label.clone())\n                .collect::<Vec<_>>()\n                .join(\", \");\n            anyhow::bail!(\n                \"{}\",\n                get_required_cli_string_with_args(\n                    \"cli-skills-multiple-locations-path\",\n                    &[(\"name\", name), (\"locations\", &locs)],\n                )\n            )\n        }\n    }\n}\n\n/// Render one skill row for `skills list` (name + version + tools + tags).\nfn print_skill(skill: &Skill) {\n    println!(\n        \"  {} {} — {}\",\n        console::style(&skill.name).white().bold(),\n        console::style(format!(\"v{}\", skill.version)).dim(),\n        skill.description\n    );","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/skills/mod.rs#L680-L716","documentation":"locate_installed_skill_dir (used by `skills audit` and `skills test --name`) errors when the name matches multiple locations — the same skill installed in several bundles and/or globally. Unlike `skills remove`, the disambiguation asked for here is an explicit path, not a --bundle flag, because audit/test accept arbitrary directories as their source.","triggerScenarios":"`skills test --name foo` where foo exists in two bundles, or in a bundle and the global dir; duplicates left after migrating skills between locations.","commonSituations":"Testing during a global-to-bundle migration; shared skill names across team bundles; verifying one specific copy among duplicates.","solutions":["Pass the explicit skill directory path as the argument instead of the bare name","Build the path from the labels in the error: bundle:<alias> → that bundle's resolved directory, global → the global skills dir","Or remove/rename the duplicate copies so exactly one location remains"],"exampleFix":"# before\nzeroclaw skills test --name foo\n\n# after\nzeroclaw skills test --name ~/.local/share/zeroclaw/skills/foo","handlingStrategy":"validation","validationCode":"// In automation, always pass an explicit directory path to audit/test\n// (bundle dirs: resolve from [skill_bundles.<alias>].directory or the default root;\n//  global: <data-dir>/skills/<name>)\nlet path = format!(\"{data_dir}/skills/{name}\");\nassert!(Path::new(&path).is_dir(), \"use a unique explicit path: {path}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use full paths when auditing/testing one copy among duplicates","Keep skill names unique across bundles and the global dir where possible","Clean up duplicates during migrations instead of living with them"],"tags":["cli","skills","audit","testing","ambiguity"],"backgroundTag":"ambiguous-reference","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}