can1357/oh-my-pi · error · Error
nameError (dynamic message from validateServerName, e.g. "Se
Error message
nameError (dynamic message from validateServerName, e.g. "Server name cannot be empty")
What it means
addMCPServer validates the requested server name via validateServerName before writing config; a failing name (empty, >100 chars, or containing characters outside [a-zA-Z0-9_.:-]) becomes the thrown Error message directly (e.g. 'Server name cannot be empty', 'Server name is too long (max 100 characters)', 'Server name can only contain letters, numbers, dash, underscore, dot, and colon').
Source
Thrown at packages/coding-agent/src/mcp/config-writer.ts:114
// sanitize them via createMCPToolName) and `/mcp reauth` writes such names back
// as a user-config override that shadows the discovered entry.
if (!/^[a-zA-Z0-9_.:-]+$/.test(name)) {
return "Server name can only contain letters, numbers, dash, underscore, dot, and colon";
}
return undefined;
}
/**
* Add an MCP server to a config file.
* Validates the config before writing.
*
* @throws Error if server name already exists or validation fails
*/
export async function addMCPServer(filePath: string, name: string, config: MCPServerConfig): Promise<void> {
// Validate server name
const nameError = validateServerName(name);
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}`);
}View on GitHub (pinned to 9690622007)
Solutions
- Provide a non-empty name using only letters, numbers, dash, underscore, dot, and colon.
- Shorten the name to ≤100 characters.
- Sanitize the name in the calling wizard/command before invoking addMCPServer (call validateServerName yourself for early feedback).
- Use a short id like 'my-server-1' rather than a label or path.
Example fix
// before await addMCPServer(path, "My MCP Server / v2", config); // after await addMCPServer(path, "my-mcp-server-v2", config);
Defensive patterns
Strategy: validation
Validate before calling
import { validateServerName } from "./config-writer";
function assertValidName(name: string): void {
const err = validateServerName(name);
if (err) throw new Error(`Pre-check: ${err}`);
} Type guard
function isValidServerName(name: string): boolean {
return name.length > 0 && name.length <= 100 && /^[a-zA-Z0-9_.:-]+$/.test(name);
} Try / catch
try {
await addMCPServer(path, name, config);
} catch (err) {
if (err instanceof Error && /^(Server name cannot be empty|Server name is too long|Server name can only contain)/.test(err.message)) {
console.error(`${err.message}; pick a short id like 'my-server-1'`);
return;
}
throw err;
} Prevention
- Call validateServerName in UI/wizard code before submitting the name.
- Normalize names: trim whitespace, replace spaces with dashes.
- Reject empty input early in forms and commands.
- Document the allowed charset (letters, numbers, dash, underscore, dot, colon) next to the name field.
When it happens
Trigger: Calling addMCPServer(filePath, name, config) — directly or via #handleWizardComplete / handleAddCommand — with an empty name, a name over 100 characters, or one containing spaces/slashes/unicode outside the allowed set.
Common situations: Wizard submitted with a blank name field; server name copied from a URL containing '/' or '?'; names with spaces from display labels; pasting a fully-qualified command path as the server name.
Related errors
- Invalid OMP profile "${profile}". Profile names must match $
- Cannot register custom API "${api}": built-in API names are
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains a provider id wit
- ${name} path does not exist: ${trimmed}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1e144dd12e6c7d4f.
Report an issue: GitHub.