Hmbown/CodeWhale · error · anyhow::Error

Command failed with exit code

Error message

Command failed with exit code {exit_code}

What it means

A sandboxed command (spawned by the sandbox runner in the TUI CLI) finished and returned a non-success exit status. After printing any sandbox denial message, the wrapper bails with the observed exit code so callers see the child's failure as an error rather than silently succeeding.

Solutions

  1. Inspect the command's stderr/stdout printed before this error to find the real failure.
  2. If a sandbox denial message was shown, adjust the sandbox policy (e.g. grant network or writable roots).
  3. Fix the underlying command invocation and re-run.

Example fix

// before: policy lacks network for a curl-based build step
parse_sandbox_policy("workspace-write")
// after
parse_sandbox_policy("workspace-write") // plus network_access: true in policy config
Defensive patterns

Strategy: try-catch

Try / catch

match run_sandboxed(cmd).await {
    Err(e) if e.to_string().contains("Command failed with exit code") => {
        // inspect printed stderr/denial message, decide on policy fix vs command fix
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Running a command through the sandbox helper where the spawned process exits non-zero and no timeout occurred (`status.success()` is false).

Common situations: The command itself failed (bad args, missing file), or the sandbox denied an operation and the process exited with an error code — check the printed denial message and stderr above the bail.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/43f77d090e44bc9c. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/lib.rs:10599

        let exit_code = status.code().unwrap_or(-1);
        let sandbox_type = exec_env.sandbox_type;
        let sandbox_denied = SandboxManager::was_denied(sandbox_type, exit_code, &stderr_str);

        if !stdout.is_empty() {
            print!("{}", String::from_utf8_lossy(&stdout));
        }
        if !stderr.is_empty() {
            eprint!("{stderr_str}");
        }
        if sandbox_denied {
            eprintln!(
                "{}",
                SandboxManager::denial_message(sandbox_type, &stderr_str)
            );
        }

        if !status.success() {
            bail!("Command failed with exit code {exit_code}");
        }
    } else {
        let _ = child.kill();
        let _ = child.wait();
        bail!("Command timed out after {}ms", timeout.as_millis());
    }
    Ok(())
}

fn parse_sandbox_policy(
    policy: &str,
    network: bool,
    writable_root: Vec<PathBuf>,
    exclude_tmpdir: bool,
    exclude_slash_tmp: bool,
) -> Result<crate::sandbox::SandboxPolicy> {
    use crate::sandbox::SandboxPolicy;

View on GitHub (pinned to 73e0f67d83)