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

  1. Supply a concrete default before expansion: expandRemotePath(cfg.workdir || '~/hermes').
  2. Make the path required in the remote settings UI and validate non-empty before save.
  3. 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

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


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