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

launching {}: {e}

Error message

launching {}: {e}

What it means

macOS-only final step: open_macos_app_detached() failed to relaunch the freshly updated Hermes.app (the error names the bundle path), so the updater cannot hand off to the new version. The update itself already succeeded; only the automatic restart failed. The updater sleeps ~150ms after launching and then exits the Tauri app.

Source

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

#[cfg(not(target_os = "macos"))]
async fn install_macos_app_update(
    _app: &AppHandle,
    _install_root: &Path,
    target_app: &Path,
) -> Result<PathBuf> {
    Ok(target_app.to_path_buf())
}

async fn remove_dir_if_exists(path: &Path) {
    if path.exists() {
        let _ = tokio::fs::remove_dir_all(path).await;
    }
}

#[cfg(target_os = "macos")]
async fn launch_macos_app_and_exit(app: &AppHandle, target_app: &Path) -> Result<()> {
    crate::bootstrap::open_macos_app_detached(target_app)
        .map_err(|e| anyhow!("launching {}: {e}", target_app.display()))?;
    tokio::time::sleep(std::time::Duration::from_millis(150)).await;
    app.exit(0);
    Ok(())
}

#[cfg(not(target_os = "macos"))]
async fn launch_macos_app_and_exit(_app: &AppHandle, _target_app: &Path) -> Result<()> {
    Ok(())
}

// ---------------------------------------------------------------------------
// Event helpers — keep emit shape identical to bootstrap.rs so the UI is reused
// ---------------------------------------------------------------------------

fn stage_info(name: &str, title: &str) -> StageInfo {
    StageInfo {
        name: name.to_string(),
        title: title.to_string(),

View on GitHub (pinned to c896c09c42)

Solutions

  1. Simply double-click the updated Hermes.app in Finder — the update is complete; only auto-relaunch failed.
  2. If macOS blocks it: System Settings > Privacy & Security > allow, or `xattr -dr com.apple.quarantine /Applications/Hermes.app`.
  3. Re-sign or properly sign the built app if ad-hoc signing trips Gatekeeper each update.
  4. Retry launching after a few seconds if LaunchServices was momentarily stale.
Defensive patterns

Strategy: fallback

Validate before calling

// Verify the swapped bundle is launchable before trying to relaunch.
fn bundle_launchable(app: &std::path::Path) -> bool {
    app.join("Contents").join("MacOS").is_dir()
        && !xattr_quarantined(app)
}

#[cfg(target_os = "macos")]
fn xattr_quarantined(p: &std::path::Path) -> bool {
    std::process::Command::new("/usr/bin/xattr").arg(p).output()
        .map(|o| String::from_utf8_lossy(&o.stdout).contains("com.apple.quarantine"))
        .unwrap_or(false)
}

Try / catch

// Update already succeeded — degrade to a manual-restart hint instead of a scary failure.
match crate::bootstrap::open_macos_app_detached(target_app) {
    Ok(()) => { tokio::time::sleep(Duration::from_millis(150)).await; app.exit(0); }
    Err(e) => {
        emit_log(&format!("update finished; auto-relaunch failed ({}). Open {} manually.", e, target_app.display()));
        app.exit(0); // success exit: the update itself completed
    }
}

Prevention

When it happens

Trigger: The just-swapped bundle is quarantined or flagged by Gatekeeper so `open`/launch services refuses it; the bundle's executable is missing or not executable; launch services database stale right after the swap; security software blocking the launch.

Common situations: xattr -dr com.apple.quarantine (run right after the swap) raced or failed; unsigned/ad-hoc build being relaunched under stricter Gatekeeper; LaunchServices still caching the old bundle identity immediately after the rename-based swap.

Related errors


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