Hmbown/CodeWhale · error · anyhow
A managed, project or plugin connector already uses this…
Error message
A managed, project or plugin connector already uses this name
What it means
Before inserting the imported server, apply checks that the name is not already taken by a managed, project, or plugin connector — checked against both the merged view (`context.merged()`) and the file being mutated (`config.servers`). Name collisions would create ambiguous connector references, so approval is refused.
Solutions
- Rename the existing server or the imported one in its source config so the names differ.
- Remove the existing duplicate connector if the imported one should replace it.
- Decline this candidate and import the source under a different name after editing the source config.
Example fix
// before (source config)
{"mcpServers": {"fetch": {...}}}
// after
{"mcpServers": {"fetch-from-claude": {...}}} Defensive patterns
Strategy: validation
Validate before calling
let name = &candidate.name;
let taken = context.merged()?.servers.contains_key(name)
|| config.servers.contains_key(name);
if taken { eprintln!("name {name} already used; rename before importing"); } Try / catch
match apply_reviewed_import(...) {
Err(e) if e.to_string().contains("already uses this name") => {
// rename in the source config or remove the existing connector, then retry
}
other => other?,
} Prevention
- Give imported servers unique, source-qualified names
- Check existing config for name collisions before previewing
- Avoid generic names like "fetch" or "filesystem" in shared configs
When it happens
Trigger: Approving an import whose candidate server name collides with an existing managed/project/plugin MCP server of the same name in the codewhale config.
Common situations: Two external clients export a server with the same generic name (e.g. "filesystem", "fetch"); the user already added that connector manually; a previous import already claimed the name.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Invalid MCP entry; contents omitted
- MCP import failed
- MCP import preview failed
- No external MCP candidate named
- Refusing to import ' ': (enabled=false is a hard block)
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/9d66e6f3673896a9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/external_import.rs:688
);
let (candidate, revision) = super::mutate_config(context.mcp_path, Some(revision), |config| {
let (candidates, _) = context.discover();
let candidate = candidates
.into_iter()
.find(|candidate| candidate_id(candidate) == id)
.ok_or_else(|| {
anyhow::anyhow!("Reviewed source is unavailable; refresh the import preview")
})?;
anyhow::ensure!(
candidate.content_hash == hash,
"Source changed; refresh the import preview"
);
if decision == ImportDecision::Approve {
anyhow::ensure!(
!source_blocked(context, &candidate),
"Source is disabled or its workspace is untrusted"
);
anyhow::ensure!(
!context.merged()?.servers.contains_key(&candidate.name)
&& !config.servers.contains_key(&candidate.name),
"A managed, project or plugin connector already uses this name"
);
let mut server = candidate.server.clone();
server.enabled = false;
server.disabled = true;
config.servers.insert(candidate.name.clone(), server);
}
Ok(candidate)
})?;
let decisions = HashMap::from([(candidate.name.clone(), decision)]);
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |time| time.as_secs());
let consent_recorded = persist_decisions(
&context.codewhale_home.join("mcp-import-consent.json"),
std::slice::from_ref(&candidate),View on GitHub (pinned to 73e0f67d83)