can1357/oh-my-pi · error · Error
Server "${name}" not found in ${filePath}
Error message
Server "${name}" not found in ${filePath} What it means
removeMCPServer() throws when the named server does not exist in the target config file. Inside the config lock it reads the config and throws if existing.mcpServers[name] is absent, so callers get a clear message naming both the server and the file instead of a silent no-op.
Source
Thrown at packages/coding-agent/src/mcp/config-writer.ts:190
[name]: config,
},
};
await writeMCPConfigFile(filePath, updated);
});
}
/**
* Remove an MCP server from a config file.
*
* @throws Error if server doesn't exist
*/
export async function removeMCPServer(filePath: string, name: string): Promise<void> {
// Serialize the read-modify-write (see addMCPServer).
await withConfigLock(filePath, async () => {
const existing = await readMCPConfigFile(filePath);
if (!existing.mcpServers?.[name]) {
throw new Error(`Server "${name}" not found in ${filePath}`);
}
const { [name]: _removed, ...remaining } = existing.mcpServers;
const updated: MCPConfigFile = {
...existing,
mcpServers: remaining,
};
await writeMCPConfigFile(filePath, updated);
});
}
/**
* Get a specific server config from a file.
* Returns undefined if server doesn't exist.
*/
export async function getMCPServer(filePath: string, name: string): Promise<MCPServerConfig | undefined> {
const config = await readMCPConfigFile(filePath);
return config.mcpServers?.[name];View on GitHub (pinned to 9690622007)
Solutions
- Check the exact name in the config file at filePath (grep for the name).
- Confirm you are editing the file the server is actually defined in (global vs project config).
- Trim/copy the name exactly as it appears, including any namespace prefix and colon.
- Make cleanup scripts idempotent: check existence before removing and treat absence as success.
- If it may not exist, use readMCPConfigFile first: if (!cfg.mcpServers?.[name]) skip the remove call.
Example fix
// before
await removeMCPServer(cfgPath, name); // throws if absent
// after
const cfg = await readMCPConfigFile(cfgPath);
if (cfg.mcpServers?.[name]) {
await removeMCPServer(cfgPath, name);
} 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]) return; // nothing to remove; skip
copyExactNameFromConfig(name); Type guard
function isKnownServer(cfg: { mcpServers?: Record<string, unknown> }, name: string): boolean {
return Object.prototype.hasOwnProperty.call(cfg.mcpServers ?? {}, name);
} Try / catch
try {
await removeMCPServer(cfgPath, name);
} catch (e) {
if (e instanceof Error && e.message.includes('not found in')) {
return; // idempotent delete: already gone
}
throw e;
} Prevention
- Check existence in the target file before removing.
- Copy server names exactly (case, whitespace, namespace prefix) from the config.
- Confirm which file (global vs project) defines the server.
- Make delete/cleanup flows idempotent so re-runs don't fail.
When it happens
Trigger: Calling removeMCPServer(filePath, name) (or #handleRemove / handleRemoveCommand) when the config file has no mcpServers entry under that exact name — wrong name, wrong file, or the entry lives in a different config source (project vs global config).
Common situations: Server was already removed (double delete or rerun script); name mismatch (case sensitivity, whitespace, missing namespace prefix like "plugin:server"); the server is defined in project .omp/mcp.json but you are editing the global file; config was regenerated and lost the entry.
Related errors
- Invalid server config: ${errors.join("; ")}
- Server "${name}" already exists 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/5695b672841e0b79.
Report an issue: GitHub.