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
- Read the embedded stderr snippet — it identifies the root cause (auth error, 429, crash)
- Fix provider configuration via `goose configure` if the failure is auth-related
- Retry after the rate-limit window; consider a smaller model or reduced parallelism
- Narrow the review scope (`--range`, `--files`) to shorten worker lifetime
- 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
- Pre-flight providers with `goose info --check` before long reviews
- Chunk large reviews by directory to shorten worker lifetimes
- Cap parallelism and turn budgets to stay under provider quotas
- Persist worker stderr in CI logs so the 500-char snippet is never lost
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
- OAuth authentication failed for {}: {}
- Failed to create provider for OAuth: {}
- provider check failed
- --severity: {e}
- Editor exited with non-zero status: {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/6162740ba2136588.
Report an issue: GitHub.