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

waiting for child: {e}

Error message

waiting for child: {e}

What it means

Raised in run_streamed when awaiting the already-spawned child's exit status fails (child.wait().await returned Err). The process ran and its output was streamed; only the final wait syscall failed — typically the child was killed by a signal (no exit code available) or reaped/killed externally (e.g. job-object teardown, system shutdown) so tokio cannot report a status.

Source

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

                Ok(Some(l)) => emit_log(app, stage_owned.as_deref(), LogStream::Stdout, &l),
                Ok(None) => break,
                Err(e) => { tracing::warn!("stdout read error: {e}"); break; }
            },
            line = read_decoded_line(&mut err, &mut err_buf) => match line {
                Ok(Some(l)) => emit_log(app, stage_owned.as_deref(), LogStream::Stderr, &l),
                Ok(None) => {}
                Err(e) => { tracing::warn!("stderr read error: {e}"); }
            },
        }
    }
    while let Ok(Some(l)) = read_decoded_line(&mut out, &mut out_buf).await {
        emit_log(app, stage_owned.as_deref(), LogStream::Stdout, &l);
    }
    while let Ok(Some(l)) = read_decoded_line(&mut err, &mut err_buf).await {
        emit_log(app, stage_owned.as_deref(), LogStream::Stderr, &l);
    }

    let status = child.wait().await.map_err(|e| anyhow!("waiting for child: {e}"))?;
    Ok(CmdResult {
        exit_code: status.code(),
    })
}

struct CmdResult {
    exit_code: Option<i32>,
}

/// Path to the venv hermes shim under an install root, regardless of existence.
fn venv_hermes(install_root: &Path) -> PathBuf {
    if cfg!(target_os = "windows") {
        install_root.join("venv").join("Scripts").join("hermes.exe")
    } else {
        install_root.join("venv").join("bin").join("hermes")
    }
}

View on GitHub (pinned to c896c09c42)

Solutions

  1. Check system logs (dmesg OOM lines, Event Viewer) for evidence the child was killed.
  2. Free memory/close other apps and retry the update.
  3. Avoid force-killing the updater or its children; close windows normally so shutdown is graceful.
  4. If it recurs on the same step, run the printed child command manually to reproduce outside the updater.
Defensive patterns

Strategy: try-catch

Try / catch

match child.wait().await {
    Ok(status) => Ok(CmdResult { exit_code: status.code() }),
    Err(e) => {
        // Child was killed/reaped (OOM, signal, external kill). Treat as failure with context,
        // and hint at system-level causes rather than retrying blindly.
        Err(anyhow!("waiting for child: {e} — the process may have been killed (OOM / signal / shutdown)"))
    }
}

Prevention

When it happens

Trigger: The child (hermes update / hermes desktop --build-only) gets SIGKILLed by an OOM killer, task manager, or a shutdown mid-run; the updater process itself is being torn down while awaiting; cgroup/container eviction kills the child.

Common situations: Memory-hungry electron build killed by the OOM killer; user ends the process tree from Task Manager/Activity Monitor mid-update; system sleep/shutdown during the update; WSL2 VM reclaiming memory during the build.

Related errors


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