can1357/oh-my-pi · error · Error
Server "${name}" already exists in ${filePath}
Error message
Server "${name}" already exists in ${filePath} What it means
addMCPServer() refuses to create a server entry whose name already exists in the target config file. Inside a per-file config lock it reads the existing config and throws if existing.mcpServers[name] is present, preventing silent overwrite of an existing server definition.
Source
Thrown at packages/coding-agent/src/mcp/config-writer.ts:131
if (nameError) {
throw new Error(nameError);
}
// Validate the config
const errors = validateServerConfig(name, config);
if (errors.length > 0) {
throw new Error(`Invalid server config: ${errors.join("; ")}`);
}
// Serialize the read-modify-write under a per-file lock so a concurrent
// mutation cannot overwrite this one (lost update). The lock also guards
// against cross-process writers sharing the same config file.
await withConfigLock(filePath, async () => {
const existing = await readMCPConfigFile(filePath);
// Check for duplicate name
if (existing.mcpServers?.[name]) {
throw new Error(`Server "${name}" already exists in ${filePath}`);
}
const updated: MCPConfigFile = {
...existing,
mcpServers: {
...existing.mcpServers,
[name]: config,
},
};
await writeMCPConfigFile(filePath, updated);
});
}
/**
* Update an existing MCP server in a config file.
* If the server doesn't exist, this will add it.
*
* @throws Error if validation failsView on GitHub (pinned to 9690622007)
Solutions
- Use updateMCPServer(filePath, name, config) to modify an existing entry instead of addMCPServer.
- Choose a different, unique server name.
- If replacement is intended, call removeMCPServer first, then addMCPServer.
- Make scripts idempotent: read the config and skip add when the name already exists.
Example fix
// before
await addMCPServer(cfgPath, "github", cfg); // throws if already present
// after
const existing = await readMCPConfigFile(cfgPath);
if (existing.mcpServers?.github) {
await updateMCPServer(cfgPath, "github", cfg);
} else {
await addMCPServer(cfgPath, "github", cfg);
} Defensive patterns
Strategy: validation
Validate before calling
import { readMCPConfigFile } from "@oh-my-pi/pi-coding-agent/mcp/config";
const cfg = await readMCPConfigFile(filePath);
if (cfg.mcpServers?.[name]) {
await updateMCPServer(filePath, name, config);
} else {
await addMCPServer(filePath, name, config);
} Type guard
function serverExists(cfg: { mcpServers?: Record<string, unknown> }, name: string): boolean {
return Boolean(cfg.mcpServers?.[name]);
} Try / catch
try {
await addMCPServer(cfgPath, name, config);
} catch (e) {
if (e instanceof Error && e.message.includes('already exists in')) {
await updateMCPServer(cfgPath, name, config); // upsert fallback
return;
}
throw e;
} Prevention
- Implement upsert (check-then-add-or-update) in any script that adds servers.
- Use unique, prefixed server names for tooling-managed entries.
- Read the current config before programmatic writes.
- Handle re-runs: treat 'already exists' as success in idempotent setup scripts.
When it happens
Trigger: Calling addMCPServer(filePath, name, config) when a server with the same name already exists in that file — e.g. running the add command or completing the wizard twice for the same server name.
Common situations: Re-running an install/setup script that adds an MCP server idempotently; accidentally reusing a name like "filesystem" that already exists; copying dotfiles between machines where the entry was already merged.
Related errors
- Invalid server config: ${errors.join("; ")}
- Server "${name}" not found in ${filePath}
- ${name}: ${message} (joined by "; ")
- Invalid OAuth URLs. Please check: Authorization URL: ${aut
- this server proxies OAuth through mcp-remote, which caches t
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bc2599ce1470a68d.
Report an issue: GitHub.