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

Another Hermes update is already running (PID {}, started {}

Error message

Another Hermes update is already running (PID {}, started {} ago). Wait for it to finish, or close the window or dashboard tab that started it, then try again.

What it means

Raised by the update flow's single-flight guard: the bootstrap completion marker doubles as a cross-process update lock (also claimed by hermes_cli/update_lock.py), and it currently names a live foreign owner PID with a start timestamp. The running update holds the lock; a second update attempt refuses to run concurrently and tells the user which PID holds it and for how long.

Source

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

            let elapsed = if mins > 0 {
                format!("{mins}m {secs}s")
            } else {
                format!("{secs}s")
            };
            let msg = format!(
                "Another Hermes update is already running (PID {}, started {} ago). \
                 Wait for it to finish, or close the window or dashboard tab that \
                 started it, then try again.",
                owner.pid, elapsed
            );
            emit(
                &app,
                BootstrapEvent::Failed {
                    stage: None,
                    error: msg.clone(),
                },
            );
            return Err(anyhow!(msg));
        }
    };

    let update_branch = update_branch_from_args(std::env::args().skip(1))
        .or_else(|| option_env_string("BUILD_PIN_BRANCH"))
        .unwrap_or_else(|| "main".to_string());
    let target_app = if cfg!(target_os = "macos") {
        target_app_from_args(std::env::args().skip(1))
    } else {
        None
    };

    let hermes = resolve_hermes(&install_root).ok_or_else(|| {
        let msg = format!(
            "Could not find the hermes CLI under {}. Is Hermes installed? \
             Re-run the installer to repair the install.",
            install_root.display()
        );

View on GitHub (pinned to c896c09c42)

Solutions

  1. Wait for the in-flight update (the message includes its age) or close the window/tab that started it, then retry.
  2. If the owner PID is a zombie from a crashed attempt, kill that PID (or fully exit Hermes) and retry.
  3. Check the update log (~/.hermes/logs/update.log) to see whether the running update is progressing before killing it.
Defensive patterns

Strategy: validation

Validate before calling

// Check the lock owner before starting an update; mirror of the updater's probe.
use std::fs;

fn update_in_progress(marker: &std::path::Path) -> Option<(u32, u64)> {
    let body = fs::read_to_string(marker).ok()?;
    let v: serde_json::Value = serde_json::from_str(&body).ok()?;
    let pid = v.get("ownerPid")?.as_u64()? as u32;
    let started = v.get("ownerStartedUnix")?.as_u64()?;
    if pid != std::process::id() && pid_alive(pid) {
        return Some((pid, started));
    }
    None
}

#[cfg(unix)]
fn pid_alive(pid: u32) -> bool {
    // kill(pid, 0): true if the process exists and we can signal it
    unsafe { libc::kill(pid as i32, 0) == 0 }
}

Try / catch

// In UI code: disable the Update button instead of surfacing this as a crash.
if let Some((pid, started)) = update_in_progress(&marker_path) {
    set_update_button_disabled(format!("Update already running (PID {pid})"));
    return Ok(());
}

Prevention

When it happens

Trigger: Two dashboard tabs (or a dashboard tab plus a manually launched updater) triggering 'Check for updates' while the first update is still running; an update spawned by the desktop app that is stuck on a slow stage; a previous update whose owner process is genuinely still alive but hung.

Common situations: User opens the dashboard in two windows and clicks update in both; a cron/scripted update overlaps a manual one; an update stalled on a network stage long enough that the user retries instead of waiting.

Related errors


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