NousResearch/hermes-agent · error · Error
Remote path must not be empty.
Error message
Remote path must not be empty.
What it means
Thrown by validateRemotePath() in the desktop app's remote-lifecycle module, which guards every remote path before it is interpolated into an SSH command via expandRemotePath(). An empty path is rejected outright because expanding it would produce a malformed or dangerous remote command.
Source
Thrown at apps/desktop/electron/remote-lifecycle.ts:101
function lockfilePath(ownershipId) {
return `${ownershipDirectory(ownershipId)}/backend.lock.json`
}
function spawnLogPath(ownershipId, spawnNonce) {
return `${ownershipDirectory(ownershipId)}/${validateSpawnNonce(spawnNonce)}.log`
}
// shell-single-quote a value for safe interpolation into a remote command.
function shq(value) {
return `'${String(value).replace(/'/g, `'\\''`)}'`
}
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 === '~') {View on GitHub (pinned to c896c09c42)
Solutions
- Supply a concrete default before expansion: expandRemotePath(cfg.workdir || '~/hermes').
- Make the path required in the remote settings UI and validate non-empty before save.
- If empty is legitimately allowed at a call site, branch around the call instead of passing '' through to expandRemotePath().
Example fix
// before const dir = expandRemotePath(config.logDir) // after const dir = expandRemotePath(config.logDir || '~/hermes/logs')
Defensive patterns
Strategy: validation
Validate before calling
const pathInput = String(config.remotePath ?? '').trim()
if (!pathInput) {
// apply a default or reject at the UI layer before expandRemotePath runs
config.remotePath = '~/hermes'
} Try / catch
try {
return expandRemotePath(p)
} catch (e) {
if (e instanceof Error && e.message === 'Remote path must not be empty.') {
return '"$HOME"' // or apply a sane default
}
throw e
} Prevention
- Default optional remote paths to '~/...' at config load time.
- Mark the path field required in the remote settings form.
- Never pass possibly-undefined config fields directly to remote-lifecycle helpers.
When it happens
Trigger: Calling expandRemotePath() (or any path it validates) with undefined, null, '', or a value whose String(p || '') is empty — e.g. a remote config field like a workdir or log directory that was never filled in, or a default of undefined passed straight through.
Common situations: A remote backend config where the workspace/log path field is optional but downstream code assumes it is set; code defaulting a path variable to undefined instead of a concrete '~/...' default; passing an empty string from trimmed user input.
Related errors
- SSH host is required.
- Remote path must be absolute or start with ~/: "${s}"
- Unsafe SSH target: host is required.
- Unsafe SSH key path: contains control characters.
- Remote gateway session token is required.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/576df39faf868ccf.
Report an issue: GitHub.