nikivdev/code · error

{} exited with {}

Error message

{} exited with {}

What it means

`run_inherit_stdio` (src/base_tool.rs:33) spawns an external binary with inherited stdio and checks the exit `status`. If the child process terminates with a non-zero exit code (or a signal), it bails with "<binary> exited with <status>". This surfaces underlying tool failures (linters, formatters, etc.) as an anyhow error.

Source

Thrown at src/base_tool.rs:33

    for name in ["base", "db"] {
        if let Ok(path) = which::which(name) {
            return Some(path);
        }
    }

    None
}

pub fn run_inherit_stdio(bin: &Path, args: &[String]) -> Result<()> {
    let status = Command::new(bin)
        .args(args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()
        .with_context(|| format!("failed to run {} {}", bin.display(), args.join(" ")))?;
    if !status.success() {
        anyhow::bail!("{} exited with {}", bin.display(), status);
    }
    Ok(())
}

pub fn run_with_stdin(bin: &Path, args: &[String], stdin: &str) -> Result<()> {
    let mut child = Command::new(bin)
        .args(args)
        .stdin(Stdio::piped())
        .stdout(Stdio::null())
        // This path is currently only used for best-effort "task run" ingestion.
        // If the user has some other `base` binary on PATH (or an older one),
        // it may print usage/errors like "unrecognized subcommand 'ingest'".
        // We intentionally silence stderr to avoid confusing noise during normal runs.
        .stderr(Stdio::null())
        .spawn()
        .with_context(|| format!("failed to spawn {} {}", bin.display(), args.join(" ")))?;

    {

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the child tool's own stderr/stdout output (inherited, so it's already printed) for the real cause
  2. Re-run the failing binary directly with the same arguments to reproduce
  3. Fix the input/config that makes the underlying tool fail
  4. In caller code, decide whether non-zero exit should be tolerated instead of propagated
Defensive patterns

Strategy: try-catch

Validate before calling

// check the binary exists and is executable before invoking
if !bin.exists() {
    anyhow::bail!("tool not found: {}", bin.display());
}

Type guard

fn is_success(status: &std::process::ExitStatus) -> bool { status.success() }

Try / catch

match run_inherit_stdio(&bin, &args) {
    Err(e) if e.to_string().contains("exited with") => {
        eprintln!("wrapped tool failed; see its output above for the cause");
        // optionally tolerate specific exit codes here
    }
    other => other?,
}

Prevention

When it happens

Trigger: Any call to `run_inherit_stdio(bin, args)` where the spawned process returns a non-success exit code or is killed by a signal — e.g. the tool itself fails validation, file not found by the tool, or user Ctrl+C.

Common situations: The wrapped CLI tool (linter/compiler) fails on the user's code; tool misconfigured via args; tool killed by SIGKILL/OOM; sandbox denies execution inputs.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/3efefda61868d07f. Report an issue: GitHub.