zeroclaw-labs/zeroclaw · error · anyhow::Error
cli-skills-multiple-locations-path
cli-skills-multiple-locations-path
Error message
skill '{$name}' exists in multiple locations ({$locations}); pass an explicit path to disambiguate What it means
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.
Source
Thrown at src/skills/mod.rs:698
}
}
out
}
/// Locate a single installed skill directory by name (across bundles + global),
/// erroring when absent or ambiguous. Used by `audit`/`test`.
fn locate_installed_skill_dir(config: &crate::config::Config, name: &str) -> Result<PathBuf> {
let mut matches = collect_skill_locations(config, name, None);
match matches.len() {
0 => anyhow::bail!("Skill not found: {name}"),
1 => Ok(matches.remove(0).1),
_ => {
let locs = matches
.iter()
.map(|(label, _)| label.clone())
.collect::<Vec<_>>()
.join(", ");
anyhow::bail!(
"{}",
get_required_cli_string_with_args(
"cli-skills-multiple-locations-path",
&[("name", name), ("locations", &locs)],
)
)
}
}
}
/// Render one skill row for `skills list` (name + version + tools + tags).
fn print_skill(skill: &Skill) {
println!(
" {} {} — {}",
console::style(&skill.name).white().bold(),
console::style(format!("v{}", skill.version)).dim(),
skill.description
);View on GitHub (pinned to 88bb9c8533)
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
Example fix
# before zeroclaw skills test --name foo # after zeroclaw skills test --name ~/.local/share/zeroclaw/skills/foo
Defensive patterns
Strategy: validation
Validate before calling
// In automation, always pass an explicit directory path to audit/test
// (bundle dirs: resolve from [skill_bundles.<alias>].directory or the default root;
// global: <data-dir>/skills/<name>)
let path = format!("{data_dir}/skills/{name}");
assert!(Path::new(&path).is_dir(), "use a unique explicit path: {path}"); Prevention
- 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
When it happens
Trigger: `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.
Common situations: Testing during a global-to-bundle migration; shared skill names across team bundles; verifying one specific copy among duplicates.
Related errors
- cli-skills-audit-failed
- cli-skills-multiple-locations-bundle
- Some skill tests failed.
- cli-skills-agent-multiple-bundles
- Skill security audit failed: {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/0b52752df117cfef.
Report an issue: GitHub.