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 fails

View on GitHub (pinned to 9690622007)

Solutions

  1. Use updateMCPServer(filePath, name, config) to modify an existing entry instead of addMCPServer.
  2. Choose a different, unique server name.
  3. If replacement is intended, call removeMCPServer first, then addMCPServer.
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/bc2599ce1470a68d. Report an issue: GitHub.