xai-org/grok-build · error

failed to run {program}: {e}

Error message

failed to run {program}: {e}

What it means

On non-Unix platforms, `exec_command` falls back to spawning the program and waiting for its status; this error is returned when `Command::status()` fails to spawn the process (the child never ran). Unlike the Unix path, it cannot replace the process, so spawn failures surface as this anyhow error naming the program.

Source

Thrown at crates/codegen/xai-grok-pager/src/wrap_cmd.rs:208

/// Replace the current process with `program <args...>` (no PTY wrapping).
#[cfg(unix)]
fn exec_command(program: &str, args: &[String]) -> Result<()> {
    use std::os::unix::process::CommandExt;

    let err = std::process::Command::new(program).args(args).exec();

    // exec() only returns on error.
    Err(anyhow::anyhow!("failed to exec {program}: {err}"))
}

/// On non-Unix platforms, spawn and wait.
#[cfg(not(unix))]
fn exec_command(program: &str, args: &[String]) -> Result<()> {
    let status = std::process::Command::new(program)
        .args(args)
        .status()
        .map_err(|e| anyhow::anyhow!("failed to run {program}: {e}"))?;

    std::process::exit(status.code().unwrap_or(1));
}

#[cfg(all(test, unix))]
#[path = "wrap_cmd_tests.rs"]
mod tests;

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Verify the program is installed on the target platform and resolvable on PATH.
  2. On Windows ensure the name resolves with the correct executable extension or give an explicit path to the .exe.
  3. Check that spawn permissions/AV policy allow launching the binary.
  4. Use the inner `{e}` io::Error kind (NotFound/PermissionDenied) to choose between installing the tool vs fixing permissions.

Example fix

// before
exec_command("tool.sh", &args)?; // .sh not executable on Windows
// after
#[cfg(windows)]
let program = String::from("tool.exe");
#[cfg(not(windows))]
let program = String::from("tool.sh");
exec_command(&program, &args)?;
Defensive patterns

Strategy: validation

Validate before calling

fn can_spawn(program: &str) -> Result<(), String> {
    let path = std::env::var("PATH").unwrap_or_default();
    for dir in path.split(';').chain(path.split(':')) {
        let candidate = std::path::Path::new(dir).join(program);
        if candidate.is_file() { return Ok(()); }
    }
    Err(format!("{program} not found on PATH"))
}

Try / catch

match exec_command(program, &args) {
    Ok(()) => {}
    Err(e) if e.to_string().contains("not found") => {
        eprintln!("'{program}' is not installed on this platform");
        std::process::exit(127);
    }
    Err(e) => { eprintln!("spawn failed: {e:#}"); std::process::exit(1); }
}

Prevention

When it happens

Trigger: On Windows or other non-Unix targets: the program name cannot be resolved to an executable (no PATH hit, wrong extension); insufficient permissions; the program path is a directory.

Common situations: Wrapping a Unix-only tool on Windows where it was never installed; missing .exe extension handling; antivirus or policy blocking process spawn; PATH differences between the shell and the spawned environment.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/0ffd5f849a35024c. Report an issue: GitHub.