aaif-goose/goose · error

{label} subprocess exited with status {}: {}

Error message

{label} subprocess exited with status {}: {}

What it means

goose review fans out its passes to child processes (`goose run -i -`, fed prompts over stdin). After wait_with_output(), a non-zero child exit status aborts the pass with this error, which embeds the exit status and up to 500 characters of the child's stderr (truncate).

Source

Thrown at crates/goose-cli/src/commands/review/orchestrator.rs:281

        .with_context(|| format!("spawn subprocess for {label}"))?;

    if let Some(mut stdin) = child.stdin.take() {
        stdin
            .write_all(prompt.as_bytes())
            .await
            .with_context(|| format!("write prompt to {label} stdin"))?;
        // Closing stdin signals EOF to `goose run -i -`.
        drop(stdin);
    }

    let output = child
        .wait_with_output()
        .await
        .with_context(|| format!("wait on {label}"))?;

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!(
            "{label} subprocess exited with status {}: {}",
            output.status,
            truncate(&stderr, 500)
        );
    }

    let stdout = String::from_utf8_lossy(&output.stdout);
    parse_findings(&stdout)
}

/// Run the main correctness pass as N parallel subprocesses, one per
/// touched file. This replaces the older in-process `session.headless()`
/// path which:
///
/// 1. Streamed text-mode chatter to stdout (not JSONL) so findings were
///    sometimes lost in interleaved output.
/// 2. Sent the entire diff in a single prompt — large diffs (1000+
///    lines) reliably caused Gemini 3.x to short-circuit with `[]`

View on GitHub (pinned to 3810898a74)

Solutions

  1. Read the embedded stderr snippet — it identifies the root cause (auth error, 429, crash)
  2. Fix provider configuration via `goose configure` if the failure is auth-related
  3. Retry after the rate-limit window; consider a smaller model or reduced parallelism
  4. Narrow the review scope (`--range`, `--files`) to shorten worker lifetime
  5. Raise memory/turn budgets in CI if the child was killed
Defensive patterns

Strategy: retry

Try / catch

# Bash: inspect exit status + stderr tail, retry only transient causes
set +e
OUT=$(goose review --files 'src/**' 2>&1); RC=$?
set -e
if [ "$RC" -ne 0 ]; then
  printf '%s\n' "$OUT" | tail -n 5
  case "$OUT" in
    *429*|*rate*|*529*) sleep 60; exec goose review --files 'src/**' ;;
    *) exit "$RC" ;;
  esac
fi

Prevention

When it happens

Trigger: A review worker subprocess dying mid-run: provider auth failure (bad/expired key), rate limiting or 5xx from the model provider, or the child being OOM-killed in a constrained CI container.

Common situations: Large reviews hitting provider rate limits; credentials expiring between runs; memory-constrained CI killing workers; model outages surfacing as child failures.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/6162740ba2136588. Report an issue: GitHub.