{"record":{"id":"1040049147b4e850","repo":"can1357/oh-my-pi","slug":"host-name-already-exists-in-filepath","errorCode":null,"errorMessage":"Host \"${name}\" already exists in ${filePath}","messagePattern":"Host \"(.+?)\" already exists in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/ssh/config-writer.ts","lineNumber":102,"sourceCode":" */\nexport async function addSSHHost(filePath: string, name: string, hostConfig: SSHHostConfig): Promise<void> {\n\t// Validate host name\n\tconst nameError = validateHostName(name);\n\tif (nameError) {\n\t\tthrow new Error(nameError);\n\t}\n\n\t// Validate host field\n\tif (!hostConfig.host) {\n\t\tthrow new Error(\"Host address cannot be empty\");\n\t}\n\n\t// Read existing config\n\tconst existing = await readSSHConfigFile(filePath);\n\n\t// Check for duplicate name\n\tif (existing.hosts?.[name]) {\n\t\tthrow new Error(`Host \"${name}\" already exists in ${filePath}`);\n\t}\n\n\t// Add host\n\tconst updated: SSHConfigFile = {\n\t\t...existing,\n\t\thosts: {\n\t\t\t...existing.hosts,\n\t\t\t[name]: hostConfig,\n\t\t},\n\t};\n\n\t// Write back\n\tawait writeSSHConfigFile(filePath, updated);\n}\n\n/**\n * Update an existing SSH host in a config file.\n * If the host doesn't exist, this will add it.","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/ssh/config-writer.ts#L84-L120","documentation":"addSSHHost refuses to overwrite: after reading the existing config it checks hosts[name] and throws if a host with the same name already exists at that file path. Updates must go through updateSSHHost instead.","triggerScenarios":"Calling addSSHHost for a name already present in existing.hosts of the target config file; running the add CLI command twice with the same alias.","commonSituations":"Re-running an add command after a previous successful add, importing host lists that contain duplicate aliases, or users expecting add to behave as upsert.","solutions":["Use updateSSHHost(filePath, name, cfg) to modify an existing entry","Pick a different unique alias for the new host","Call removeSSHHost first if replacement is intended, then addSSHHost","Check readSSHConfigFile(filePath).hosts[name] before adding to branch add-vs-update in your handler"],"exampleFix":"// before\nawait addSSHHost(path, \"prod\", cfg); // throws if exists\n// after\nconst existing = (await readSSHConfigFile(path)).hosts?.[\"prod\"];\nif (existing) await updateSSHHost(path, \"prod\", cfg);\nelse await addSSHHost(path, \"prod\", cfg);","handlingStrategy":"validation","validationCode":"const existing = (await readSSHConfigFile(filePath)).hosts?.[name];\nif (existing) await updateSSHHost(filePath, name, cfg);\nelse await addSSHHost(filePath, name, cfg);","typeGuard":"null","tryCatchPattern":"try { await addSSHHost(p, name, cfg); } catch (e) { if (e instanceof Error && e.message.includes(\"already exists\")) await updateSSHHost(p, name, cfg); else throw e; }","preventionTips":["Check for existing entries before adding (or use an upsert helper)","Use updateSSHHost for modifications","Ensure aliases are unique across generated/imported host lists"],"tags":["ssh","duplicate","config-conflict"],"backgroundTag":"duplicate-entry-conflict","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}