NousResearch/hermes-agent · critical
Hermes backend did not become ready: ${detail}
Error message
Hermes backend did not become ready: ${detail} What it means
RuntimeError raised in load_jobs() (cron/jobs.py:1094) when reading ~/.hermes/cron/jobs.json raises an IOError that the auto-repair path could not prevent — e.g. permission denied, disk I/O error, or a read failure on a file that exists. It is distinct from the corruption branch: the file's bytes could not be read at all, so no repair is attempted.
Source
Thrown at apps/desktop/electron/backend-health.ts:168
// An explicitly missing route means the backend predates /api/health.
// So does a gate-shaped 401 on an ANONYMOUS probe: the dashboard auth
// gate runs ahead of the SPA catch-all, so a pre-/api/health backend
// rejects the unknown path as unauthenticated instead of 404 and a
// credential-free probe can never observe the 404. Timeouts, 5xx, 429,
// and non-gate 401s keep polling health.
if (!useStatusFallback && (isMissingHealthEndpointError(error) || isGatedMissingHealthError(error))) {
useStatusFallback = true
continue
}
await sleep(pollMs)
}
}
const detail = lastError instanceof Error ? lastError.message : 'timeout'
throw new Error(`Hermes backend did not become ready: ${detail}`)
}
View on GitHub (pinned to c896c09c42)
Solutions
- Check the underlying IOError in the message, then inspect permissions on jobs.json and its parent directory.
- Fix ownership/permissions: chown/chmod the file so the current user can read AND write it (cron also saves).
- Free disk space or remount a read-only filesystem read-write.
- If the file is a directory or otherwise mangled, move it aside and let cron recreate an empty jobs list.
Example fix
# shell — before: cron commands fail with 'Failed to read cron database' ls -la ~/.hermes/cron/jobs.json # owned by root:root # after sudo chown -R "$USER" ~/.hermes/cron && hermes cron list
Defensive patterns
Strategy: try-catch
Validate before calling
from pathlib import Path
from hermes_constants import get_hermes_home
jobs_file = get_hermes_home() / "cron" / "jobs.json"
if jobs_file.exists() and not jobs_file.is_file():
raise SystemExit("jobs.json is not a regular file")
if jobs_file.exists():
try:
jobs_file.read_text()
except OSError as e:
raise SystemExit(f"jobs.json unreadable: {e} — fix permissions first") Try / catch
from cron.jobs import list_jobs
try:
jobs = list_jobs()
except RuntimeError as e:
if "Failed to read cron database" in str(e):
# IO problem: check ownership/permissions of jobs.json, free disk, then retry after fix
raise Prevention
- Never run `hermes cron` commands under sudo — root-owned jobs.json breaks later runs.
- Keep ~/.hermes/cron writable by the user that runs the gateway; monitor disk space.
When it happens
Trigger: load_jobs() finds jobs.json exists but open()/read() raises OSError: file owned by another user with mode 600, a read-only or full filesystem, the file being a directory, or a transient NFS/FUSE error. Any cron operation (list/create/save via hermes cron, the cronjob tool, the scheduler tick) that loads jobs hits it.
Common situations: Running `hermes cron` under sudo previously so jobs.json is root-owned; disk full; the HERMES_HOME/profile directory was restored from a backup with wrong ownership; two profiles pointed at the same home with different users.
Related errors
- Cannot resolve ${installScriptName()}: no SOURCE_REPO_ROOT a
- ${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest
- Could not create directory: ${error.message}
- Unsafe SSH control dir: ${controlDir} is owned by uid ${st.u
- Refusing to start: could not pre-create audit log {audit_pat
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/dc45fac25a7b853a.
Report an issue: GitHub.