NousResearch/hermes-agent · warning · Error
Invalid path
Error message
Invalid path
What it means
The 'hermes:fs:writeText' IPC writes a small UTF-8 text file (e.g. a project's IDEA.md). Its first validation requires a non-empty trimmed filePath; an empty/whitespace/undefined path throws 'Invalid path' before any filesystem access. Subsequent guards (size cap, allowed roots via resolveRequestedPathForIpc, parent-exists) run after this one.
Source
Thrown at apps/desktop/electron/main.ts:11793
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')
}
const text = String(content ?? '')
if (text.length > 1_000_000) {
throw new Error('Content too large')
}
const resolved = resolveRequestedPathForIpc(expandUserPath(raw), { purpose: 'Write text file' })
if (!directoryExists(path.dirname(resolved))) {
throw new Error('Parent directory does not exist')
}
await fs.promises.writeFile(resolved, text, 'utf8')
return { path: resolved }
})View on GitHub (pinned to c896c09c42)
Solutions
- Ensure the caller has a concrete file path before invoking — guard on a truthy trimmed string
- If the path originates from a save/pick dialog, bail when the dialog is cancelled
- Remember the path is user-~ expanded and root-checked, so pass a normal absolute or ~-relative path, not empty
Example fix
// before
await ipc.invoke('hermes:fs:writeText', filePath, text)
// after
const p = filePath?.trim()
if (!p) return
await ipc.invoke('hermes:fs:writeText', p, text) Defensive patterns
Strategy: validation
Validate before calling
const p = typeof filePath === 'string' ? filePath.trim() : ''
if (!p) { notify('Choose a file path first'); return }
await ipc.invoke('hermes:fs:writeText', p, content) Type guard
function isNonEmptyPath(v: unknown): v is string { return typeof v === 'string' && v.trim().length > 0 } Try / catch
catch (e) { if (e instanceof Error && e.message === 'Invalid path') notify('File path is required') else throw e } Prevention
- Bail on cancelled save/pick dialogs before calling writeText
- Keep file-path state non-null in the component contract (make it required in props)
When it happens
Trigger: Renderer invokes writeText with '', ' ', null, or undefined as filePath — usually an uninitialized state value or a dialog that was cancelled before producing a path.
Common situations: Saving a file whose path comes from a prompt that returned null on cancel; template code running before the path state is populated.
Related errors
- Invalid rename
- "${name}" already exists
- Content too large
- Parent directory does not exist
- Invalid delete
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/f24e3c384bfe4e75.
Report an issue: GitHub.