NousResearch/hermes-agent · error · Error
Remote path must be absolute or start with ~/: "${s}"
Error message
Remote path must be absolute or start with ~/: "${s}" What it means
Thrown by validateRemotePath() when the path is non-empty and free of NUL/newlines but is neither absolute (leading /) nor home-relative (~ or ~/...). expandRemotePath() only supports those two forms because it rewrites them to '"$HOME"'-anchored or literal absolute strings inside a shell command; anything else is ambiguous on the remote host.
Source
Thrown at apps/desktop/electron/remote-lifecycle.ts:113
}
function validateRemotePath(p) {
const s = String(p || '')
if (!s) {
throw new Error('Remote path must not be empty.')
}
// eslint-disable-next-line no-control-regex -- deliberately reject NUL in remote paths
if (/[\x00\n\r]/.test(s)) {
throw new Error('Unsafe remote path: contains NUL or newline.')
}
if (s === '~' || s.startsWith('~/') || s.startsWith('/')) {
return
}
throw new Error(`Remote path must be absolute or start with ~/: "${s}"`)
}
function expandRemotePath(p) {
validateRemotePath(p)
if (p === '~') {
return '"$HOME"'
}
if (p.startsWith('~/')) {
return '"$HOME"' + shq(p.slice(1))
}
return shq(p)
}
// Resolve the remote hermes executable. An EXPLICIT path is honored strictly
// (throws a path-naming error if not executable — never silently falls back to aView on GitHub (pinned to c896c09c42)
Solutions
- Use an absolute path (/opt/hermes) or a home-relative path (~/hermes) in the remote path setting.
- If the value is meant to be relative to the remote home, prefix it: `~/${value}`.
- Update the settings UI hint/validation to require the ~/ or / prefix at entry time.
Example fix
// before
expandRemotePath(userPath) // userPath = 'hermes'
// after
const p = userPath.startsWith('/') || userPath.startsWith('~') ? userPath : `~/${userPath}`
expandRemotePath(p) Defensive patterns
Strategy: validation
Validate before calling
function isSupportedRemotePathForm(s: string): boolean {
return s === '~' || s.startsWith('~/') || s.startsWith('/')
}
const p = String(config.path ?? '')
if (!isSupportedRemotePathForm(p)) {
// normalize bare relative names to home-relative before validation
config.path = `~/${p}`
} Type guard
function isAbsoluteOrHomeRelative(p: unknown): p is string {
return typeof p === 'string' && (p === '~' || p.startsWith('~/') || p.startsWith('/'))
} Try / catch
try {
return expandRemotePath(p)
} catch (e) {
if (e instanceof Error && e.message.includes('must be absolute or start with ~/')) {
return expandRemotePath(`~/${p}`) // retry with home-relative normalization
}
throw e
} Prevention
- Show the '~/ or / required' rule in the remote path field placeholder and validate on save.
- Auto-prefix '~/' for bare relative inputs in the settings form.
- Never feed local cwd values (often relative) into remote path expansion without mapping.
When it happens
Trigger: Calling expandRemotePath('hermes'), expandRemotePath('./logs'), or expandRemotePath('x/y') — any bare or dot-relative path. The validator accepts only '~', '~/...', or '/...' and rejects everything else.
Common situations: Users entering a project-relative directory like 'hermes-agent' in a remote workdir setting; reusing a local relative cwd as a remote path; a form placeholder suggesting 'hermes' without the ~/ prefix.
Related errors
- Remote path must not be empty.
- Remote gateway session token is required.
- SSH host is required.
- Unsafe remote path: contains NUL or newline.
- Unsafe SSH target: host is required.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/2913b10e650d43a5.
Report an issue: GitHub.