NousResearch/hermes-agent · error · anyhow::Error

Hermes is still running. Close all Hermes windows and try th

Error message

Hermes is still running. Close all Hermes windows and try the update again.

What it means

Stage-2 outcome of the update flow: `hermes update` exited with a status that maps to the 'still running' arm — the CLI refused because Hermes processes were detected alive. Before overwriting files the updater must have the old desktop app (and any Hermes sessions) shut down; the emitted stage 'update' is marked Failed with this message.

Source

Thrown at apps/bootstrap-installer/src-tauri/src/update.rs:454

        Some(code) if code == UPDATE_EXIT_CONCURRENT => {
            let msg = "Hermes is still running. Close all Hermes windows and try \
                       the update again."
                .to_string();
            emit_stage(
                &app,
                "update",
                StageState::Failed,
                Some(update_ms),
                Some(msg.clone()),
            );
            emit(
                &app,
                BootstrapEvent::Failed {
                    stage: Some("update".into()),
                    error: msg.clone(),
                },
            );
            return Err(anyhow!(msg));
        }
        other => {
            let msg = format!(
                "hermes update failed (exit {:?}). See {} for details.",
                other,
                crate::paths::hermes_home()
                    .join("logs")
                    .join("update.log")
                    .display()
            );
            emit_stage(
                &app,
                "update",
                StageState::Failed,
                Some(update_ms),
                Some(msg.clone()),
            );
            emit(

View on GitHub (pinned to c896c09c42)

Solutions

  1. Close all Hermes windows, tabs, and terminals running hermes, then retry the update.
  2. Check for lingering processes (`ps aux | grep -i hermes` / Task Manager) and end them.
  3. Retry — shutdown races are timing-dependent and usually succeed on a second attempt once processes are gone.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: no hermes processes should be alive before updating.
fn hermes_running() -> bool {
    let out = if cfg!(target_os = "windows") {
        std::process::Command::new("tasklist").args(["/FI", "IMAGENAME eq hermes.exe"]).output()
    } else {
        std::process::Command::new("pgrep").args(["-f", "hermes"]).output()
    };
    out.map(|o| !o.stdout.is_empty()).unwrap_or(true) // fail closed
}

if hermes_running() {
    eprintln!("Close all Hermes windows/processes before updating.");
}

Try / catch

// Treat as retryable, not fatal: prompt the user and retry the update once processes are gone.
match exit {
    ExitCode::STILL_RUNNING => {
        emit_stage(&app, "update", StageState::Failed, Some(ms), Some("Hermes is still running".into()));
        // surface a retry affordance in the UI rather than a dead end
    }
    _ => { /* real failure: consult update.log */ }
}

Prevention

When it happens

Trigger: Running the updater while Hermes desktop windows, a dashboard tab backend, TUI sessions, or gateway processes are still alive; the stage-1 'wait for the old desktop to die' step timed out or raced a slow shutdown; a background hermes process (cron ticker, serve backend) survived the window close.

Common situations: User clicked update but left a dashboard tab open in a browser; an Electron main process took seconds to exit and the update started meanwhile; a stray `hermes serve` or gateway process from an earlier session is still running.

Related errors


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