NousResearch/hermes-agent · critical

Hermes backend did not become ready

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.

Solutions

  1. Check the underlying IOError in the message, then inspect permissions on jobs.json and its parent directory.
  2. Fix ownership/permissions: chown/chmod the file so the current user can read AND write it (cron also saves).
  3. Free disk space or remount a read-only filesystem read-write.
  4. 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

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


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

Appendix: 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)