nikivdev/code · error
multiple external CLI manifests matched {}: {}
Error message
multiple external CLI manifests matched {}: {} What it means
`resolve_external_cli_tool_in_roots` requires tool ids to resolve uniquely. When more than one manifest under the searched roots declares the same id, resolution is ambiguous and the error lists every matching manifest path.
Source
Thrown at src/external_cli.rs:391
match matches.len() {
0 => bail!(
"external CLI tool {} not found under {}",
id,
roots
.iter()
.map(|path| path.display().to_string())
.collect::<Vec<_>>()
.join(", ")
),
1 => Ok(matches.remove(0)),
_ => {
let locations = matches
.iter()
.map(|tool| tool.manifest_path.display().to_string())
.collect::<Vec<_>>()
.join(", ");
bail!(
"multiple external CLI manifests matched {}: {}",
id,
locations
)
}
}
}
fn resolved_from_link_record(
record: &ExternalCliLinkRecord,
registration_path: Option<PathBuf>,
) -> Result<ResolvedExternalCliTool> {
let manifest = read_manifest(&record.manifest_path)?;
if manifest.id != record.id {
bail!(
"external CLI link {} points to manifest with mismatched id {}",
record.id,
manifest.idView on GitHub (pinned to a747e741ae)
Solutions
- Remove or rename the duplicate manifest so only one manifest with that id remains across the roots.
- Narrow the `roots` list passed to resolution so only the intended root is searched.
- Change the `id` in one of the manifests if they are genuinely different tools.
- Delete the stale copy left by a previous install.
Example fix
// before let roots = vec![system_root, local_root, stale_sandbox_root]; // after let roots = vec![local_root];
Defensive patterns
Strategy: validation
Validate before calling
fn assert_unique_ids(roots: &[PathBuf]) -> Result<(), String> {
let mut seen: HashMap<String, PathBuf> = HashMap::new();
for root in roots {
for m in walk_manifests(root)? {
if let Some(prev) = seen.insert(m.id.clone(), m.path.clone()) {
return Err(format!("duplicate id {} at {:?} and {:?}", m.id, prev, m.path));
}
}
}
Ok(())
} Try / catch
match resolver.resolve_external_cli_tool(id, &roots) {
Err(e) if e.to_string().contains("multiple external CLI manifests") => {
eprintln!("{e}; narrowing roots to the local install");
resolver.resolve_external_cli_tool(id, &[local_root.clone()])
}
other => other,
} Prevention
- Keep one install location per tool id; delete stale copies.
- Use precedence (e.g. local root first, alone) instead of overlapping roots.
- Audit roots for duplicate ids in CI.
- Namespace ids per project to avoid collisions between tools.
When it happens
Trigger: Calling `resolve_external_cli_tool` (or `resolves_manifest_from_roots`) where two or more manifests under the roots have the same `id` value.
Common situations: A tool installed both system-wide (in one root) and locally (in another root); a copy of a manifest left in a test/sandbox directory that is also a root; duplicate manifests from re-running an installer into different roots.
Related errors
- {} has no exec.run argv in {}
- external CLI tool {} not found under {}
- Missing GEMINI_API_KEY/GOOGLE_API_KEY (set env var or add to
- AI task '{}' is ambiguous. Matches: - {} Try one of the fu
- multiple session-doc queue entries match `{session_hint}`
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/5db22a8018b00849.
Report an issue: GitHub.