Hmbown/CodeWhale · error
Model response incomplete: provider stop reason `{}`; the JS
Error message
Model response incomplete: provider stop reason `{}`; the JSON receipt records success=false. What it means
JSON-mode variant of the incomplete-stop-reason guard: the one-shot run first prints a JSON receipt (which records success=false and the stop reason), then bails with this message for the same incomplete reasons: output limits (length, max_tokens, max_output_tokens), content_filter, model_context_window_exceeded, or 'incomplete:'-prefixed Responses API statuses.
Source
Thrown at crates/tui/src/lib.rs:10101
let usage = response.usage.clone();
let mut output = String::new();
for block in response.content {
if let ContentBlock::Text { text, .. } = block {
output.push_str(&text);
}
}
println!(
"{}",
serde_json::to_string_pretty(&one_shot_exec_json_receipt(
provider,
model,
output,
stop_reason.clone(),
usage,
))?
);
if is_incomplete_stop_reason(stop_reason.as_deref()) {
anyhow::bail!(
"Model response incomplete: provider stop reason `{}`; the JSON receipt records success=false.",
stop_reason_detail(stop_reason.as_deref())
);
}
Ok(())
}
fn one_shot_exec_json_receipt(
provider: String,
model: String,
output: String,
stop_reason: Option<String>,
usage: crate::models::Usage,
) -> serde_json::Value {
let incomplete = crate::models::is_incomplete_stop_reason(stop_reason.as_deref());
let error = incomplete.then(|| {
format!(
"Model response incomplete: provider stop reason `{}`.",View on GitHub (pinned to 8880682c63)
Solutions
- Read the receipt's stop_reason field and fix the named cause (raise the output budget, shrink input, or change model)
- Check the receipt's success flag rather than assuming printed JSON means the command worked
- Split oversized tasks into smaller one-shot calls so answers fit the budget
- For content_filter stops, adjust the prompt or policy instead of retrying
Example fix
# before: receipt printed, exit code ignored out=$(sandbox exec --json 'summarize this 50k-line log') # after: branch on the receipt, then the exit code out=$(sandbox exec --json 'summarize this 50k-line log') || echo "incomplete: $out" >&2
Defensive patterns
Strategy: type-guard
Type guard
// The receipt is structured output: branch on its fields, not on stderr text
#[derive(serde::Deserialize)]
struct OneShotReceipt {
success: bool,
stop_reason: Option<String>,
}
fn failed_by_stop_reason(raw: &str) -> Option<String> {
serde_json::from_str::<OneShotReceipt>(raw)
.ok()
.filter(|r| !r.success)
.and_then(|r| r.stop_reason)
} Try / catch
// Script pattern: parse the receipt from stdout, then honor the exit code
const out = runOneShotJson(prompt);
const receipt = JSON.parse(out);
if (receipt.success === false && /length|max_tokens|content_filter/.test(receipt.stop_reason ?? '')) {
return retryWithHigherBudget(prompt);
} Prevention
- Always parse the JSON receipt; printed JSON does not imply success
- Size output budgets to the task before one-shot runs
- Split oversized tasks so answers fit the configured limit
- Send content_filter receipts to prompt review instead of retrying
When it happens
Trigger: One-shot runs with JSON output enabled where the answer exceeds the output token limit, the context window is exceeded, or a content filter stops generation; the receipt on stdout is valid JSON, but the process exit code is non-zero.
Common situations: Automation parsing receipts hitting silent truncation, structured pipelines assuming receipt presence implies success, low token defaults in CI-invoked one-shot runs.
Related errors
- Model response incomplete: provider stop reason `{}`; the pa
- provider stream error: {error}
- Compaction summary response incomplete: provider stop reason
- auto-route classifier response incomplete: provider stop rea
- parallel(): expected an array of thunks
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5a84549c2ed2594a.
Report an issue: GitHub.