NousResearch/hermes-agent · warning · Error

"${name}" already exists

Error message

"${name}" already exists

What it means

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.

Source

Thrown at apps/desktop/electron/main.ts:11777

// Rename a file/folder in place. The renderer passes the existing path + a new
// base name; the destination is resolved in the SAME parent dir so a rename can
// never move the item elsewhere or traverse out. Rejects on a name collision.
ipcMain.handle('hermes:fs:rename', async (_event, targetPath, newName) => {
  const src = String(targetPath || '').trim()
  const name = String(newName || '').trim()

  if (!src || !name || name === '.' || name === '..' || name.includes('/') || name.includes('\\')) {
    throw new Error('Invalid rename')
  }

  const dst = path.join(path.dirname(src), name)

  if (dst === src) {
    return { path: dst }
  }

  if (fs.existsSync(dst)) {
    throw new Error(`"${name}" already exists`)
  }

  await fs.promises.rename(src, dst)

  return { path: dst }
})

// Write a small UTF-8 text file (e.g. a project's IDEA.md at creation). The path
// is hardened (resolveRequestedPathForIpc) and the parent must already exist —
// this never creates directory trees or escapes the allowed roots, and content
// is size-capped so it can't be abused as a bulk-write primitive.
ipcMain.handle('hermes:fs:writeText', async (_event, filePath, content) => {
  const raw = String(filePath || '').trim()

  if (!raw) {
    throw new Error('Invalid path')
  }

View on GitHub (pinned to c896c09c42)

Solutions

  1. Choose a different name, or delete/trash the existing item first (hermes:fs:trash) if it is truly disposable
  2. Pre-check in the UI: existsSync-style duplicate detection or a directory listing before submitting the rename
  3. On macOS/Windows remember name comparison is case-insensitive at the FS level even though the guard compares strings

Example fix

// before
await ipc.invoke('hermes:fs:rename', path, name)

// after
const siblings = await ipc.invoke('hermes:fs:list', dirname(path))
if (siblings.some(s => s.name === name)) return setError(`"${name}" already exists`)
await ipc.invoke('hermes:fs:rename', path, name)
Defensive patterns

Strategy: validation

Validate before calling

const siblings: { name: string }[] = await listDir(dirname(src))
if (siblings.some(s => s.name === name)) { setRenameError(`"${name}" already exists`); return }
await ipc.invoke('hermes:fs:rename', src, name)

Try / catch

catch (e) { if (e instanceof Error && e.message.endsWith('already exists')) setRenameError(e.message) else throw e }

Prevention

When it happens

Trigger: 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.

Common situations: Renaming a file to 'untitled' when 'untitled' already exists; merge conflicts leaving duplicate-named files; batch UIs auto-generating names that clash.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/c86146ffaa10f0b2. Report an issue: GitHub.