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

write bootstrap marker failed: {err:#}

Error message

write bootstrap marker failed: {err:#}

What it means

Raised when write_bootstrap_complete_marker() fails to persist the completion marker JSON under the install root (create the marker directory, serialize the JSON, or write the file failed). The marker records schemaVersion, pinned commit/branch, and completion time, and doubles as the cross-process update lock shared with `hermes update` (hermes_cli/update_lock.py). Because the UI relies on the marker to leave the progress state, the installer treats an unwritable marker as a hard failure of an otherwise-finished install.

Source

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

        .hermes_home
        .clone()
        .unwrap_or_else(|| crate::paths::hermes_home().to_string_lossy().into_owned());
    let install_root = PathBuf::from(&hermes_home).join("hermes-agent");

    // Marker publish is terminal for this run: a write failure must emit Failed
    // so the UI leaves the progress state (it does not poll get_bootstrap_status).
    let marker = match write_bootstrap_complete_marker(&install_root, &pin) {
        Ok(marker) => marker,
        Err(err) => {
            let msg = format!("write bootstrap marker failed: {err:#}");
            emit_event(
                &app,
                BootstrapEvent::Failed {
                    stage: None,
                    error: msg.clone(),
                },
            );
            return Err(anyhow!(msg));
        }
    };

    // Copy ourselves to HERMES_HOME/hermes-setup.exe so the desktop app can
    // re-invoke us with `--update` and shortcuts have a stable target. This is
    // a one-shot install concern; an `--update` re-invocation no-ops because
    // we're already running from that path. Best-effort — a failure here must
    // not fail an otherwise-successful install.
    if let Err(err) = crate::paths::copy_self_to_hermes_home() {
        tracing::warn!(?err, "failed to copy installer into HERMES_HOME (non-fatal)");
        emit_log(&format!(
            "[bootstrap] warning: could not stage updater binary: {err}"
        ));
    }

    emit_event(
        &app,
        BootstrapEvent::Complete {

View on GitHub (pinned to c896c09c42)

Solutions

  1. Free disk space and verify write access to the marker path shown in the error's install root (create the directory by hand as a test).
  2. Delete the stale marker file so the installer can recreate it with fresh permissions.
  3. Re-run the installer elevated (Windows) or fix ownership of HERMES_HOME (chmod/chown on macOS/Linux).
  4. Temporarily disable/reconfigure antivirus real-time scanning for HERMES_HOME and retry.
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
use std::fs;

fn marker_writable(install_root: &Path) -> std::io::Result<()> {
    let marker = crate::paths::likely_bootstrap_marker(install_root);
    if let Some(parent) = marker.parent() {
        fs::create_dir_all(parent)?;
        let probe = parent.join(".write-probe");
        fs::write(&probe, b"x")?;
        let _ = fs::remove_file(&probe);
    }
    Ok(())
}

// Run before install: bail early with a clear message if the marker can't be written.
if let Err(e) = marker_writable(&install_root) {
    eprintln!("HERMES_HOME not writable: {e}");
}

Try / catch

match write_bootstrap_complete_marker(&install_root, &pin) {
    Ok(m) => m,
    Err(err) => {
        // Install itself succeeded; surface as recoverable, point user at permissions/disk.
        emit_event(&app, BootstrapEvent::Failed { stage: None,
            error: format!("install finished but the completion marker could not be written: {err:#}. Check disk space and permissions on the install root.") });
        return Err(anyhow!("write bootstrap marker failed: {err:#}"));
    }
}

Prevention

When it happens

Trigger: Calling the bootstrap finish path when HERMES_HOME or the install root is on a read-only/full disk, when the marker's parent directory cannot be created (permission denied), when serde_json serialization of the marker value fails (practically never), or when antivirus/another process holds the marker file open with an exclusive lock on Windows.

Common situations: Disk full on the drive holding HERMES_HOME; running the installer without write permission to the user profile dir; a stale marker file with restrictive ACLs from a previous run under a different account; OneDrive/antivirus locking .json files in the home directory.

Related errors


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