{"record":{"id":"c86146ffaa10f0b2","repo":"NousResearch/hermes-agent","slug":"name-already-exists","errorCode":null,"errorMessage":"\"${name}\" already exists","messagePattern":"\"(.+?)\" already exists","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/desktop/electron/main.ts","lineNumber":11777,"sourceCode":"// Rename a file/folder in place. The renderer passes the existing path + a new\n// base name; the destination is resolved in the SAME parent dir so a rename can\n// never move the item elsewhere or traverse out. Rejects on a name collision.\nipcMain.handle('hermes:fs:rename', async (_event, targetPath, newName) => {\n  const src = String(targetPath || '').trim()\n  const name = String(newName || '').trim()\n\n  if (!src || !name || name === '.' || name === '..' || name.includes('/') || name.includes('\\\\')) {\n    throw new Error('Invalid rename')\n  }\n\n  const dst = path.join(path.dirname(src), name)\n\n  if (dst === src) {\n    return { path: dst }\n  }\n\n  if (fs.existsSync(dst)) {\n    throw new Error(`\"${name}\" already exists`)\n  }\n\n  await fs.promises.rename(src, dst)\n\n  return { path: dst }\n})\n\n// Write a small UTF-8 text file (e.g. a project's IDEA.md at creation). The path\n// is hardened (resolveRequestedPathForIpc) and the parent must already exist —\n// this never creates directory trees or escapes the allowed roots, and content\n// is size-capped so it can't be abused as a bulk-write primitive.\nipcMain.handle('hermes:fs:writeText', async (_event, filePath, content) => {\n  const raw = String(filePath || '').trim()\n\n  if (!raw) {\n    throw new Error('Invalid path')\n  }\n","sourceCodeStart":11759,"sourceCodeEnd":11795,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/electron/main.ts#L11759-L11795","documentation":"The rename IPC computes the destination as path.join(dirname(src), name) and refuses to overwrite: if fs.existsSync(dst) is true (and dst !== src), it throws '\"<name>\" already exists'. This is a collision guard so an in-place rename never clobbers an existing file or folder.","triggerScenarios":"Renaming to a name that already exists in the same directory — including case-only collisions on case-insensitive filesystems (macOS/Windows: 'readme.md' vs 'README.md' when dst !== src does not hold, so case changes pass, but sibling files differing only in extension case can collide), or renaming to the current name of another item.","commonSituations":"Renaming a file to 'untitled' when 'untitled' already exists; merge conflicts leaving duplicate-named files; batch UIs auto-generating names that clash.","solutions":["Choose a different name, or delete/trash the existing item first (hermes:fs:trash) if it is truly disposable","Pre-check in the UI: existsSync-style duplicate detection or a directory listing before submitting the rename","On macOS/Windows remember name comparison is case-insensitive at the FS level even though the guard compares strings"],"exampleFix":"// before\nawait ipc.invoke('hermes:fs:rename', path, name)\n\n// after\nconst siblings = await ipc.invoke('hermes:fs:list', dirname(path))\nif (siblings.some(s => s.name === name)) return setError(`\"${name}\" already exists`)\nawait ipc.invoke('hermes:fs:rename', path, name)","handlingStrategy":"validation","validationCode":"const siblings: { name: string }[] = await listDir(dirname(src))\nif (siblings.some(s => s.name === name)) { setRenameError(`\"${name}\" already exists`); return }\nawait ipc.invoke('hermes:fs:rename', src, name)","typeGuard":null,"tryCatchPattern":"catch (e) { if (e instanceof Error && e.message.endsWith('already exists')) setRenameError(e.message) else throw e }","preventionTips":["Check the target directory listing for the new name before submitting","On case-insensitive filesystems compare names case-insensitively","Offer an auto-suffix ('name (2)') when a collision is detected"],"tags":["filesystem","validation","collision","ipc","desktop"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}