Hmbown/CodeWhale · error
Model stream ended with no answer or tool call.
Error message
Model stream ended with no answer or tool call.
What it means
Same condition as its sibling error but with no stop_reason available: the model stream simply ended and no answer text or tool call was produced. The turn loop logs a warning, records a turn error, and sends a classified error event to the UI. It guards against providers returning empty streams without explanation.
Solutions
- Retry the send — the engine counts nothing-streamed turns and can retry; a transient provider blip is the most common cause.
- Check provider status/health and network connectivity to the endpoint.
- Verify the model ID and API version in configuration are valid for streaming.
- Inspect session logs for preceding stream errors that may explain the empty stream.
Defensive patterns
Strategy: retry
Try / catch
// empty-stream failures are usually transient: retry with a small cap
let mut attempts = 0;
while attempts < 3 {
match send_message(prompt).await {
Err(e) if e.contains("no answer or tool call") => { attempts += 1; continue; }
r => break r,
}
} Prevention
- Use stable, GA model endpoints rather than experimental ones for critical flows.
- Keep network paths to the provider reliable; avoid flaky proxies.
- Watch provider status pages and fail over during incidents.
When it happens
Trigger: run_turn detects stream end (Ok(None)) with zero accumulated content and no tool calls, and stop_reason is None or non-string. Reached from handle_send_message.
Common situations: Provider outages or load-shedding returning empty 200 streams; flaky networks closing SSE connections prematurely; buggy or experimental model endpoints emitting no deltas; API version regressions in streaming format.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- Model returned terminal stop reason
- stream_stall
- Antigravity cloud-code is stream-only; blocking…
- Antigravity cloud-code stream ended without a text part
- Compaction summary response was unusable: no text was…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/d379bb7af83a8165.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/core/engine/turn_loop.rs:2610
"Model reached the response output limit with no answer or tool call (requested allowance: {} tokens, including reasoning).",
stream_request.max_tokens
)
} else if has_provider_reasoning {
let reason = codewhale_models::stop_reason_detail(stop_reason.as_deref());
format!(
"Model returned reasoning but no answer or tool call; the provider response was incomplete (stop reason: {}).",
reason
.chars()
.flat_map(char::escape_default)
.take(120)
.collect::<String>()
)
} else if let Some(reason) = stop_reason.as_deref() {
format!(
"Model returned terminal stop reason `{reason}` with no answer or tool call."
)
} else {
"Model stream ended with no answer or tool call.".to_string()
};
crate::logging::warn(&message);
turn_error = Some(message.clone());
let _ = self
.tx_event
.send(Event::error(ErrorEnvelope::classify(message, true)))
.await;
}
if turn_error.is_none() {
if !turn.budget_exhausted_final_report {
turn.stop_diagnostics.reason = Some(TurnStopReason::ProviderNoToolCall);
}
// This branch received no calls and dispatches no tools.
turn.stop_diagnostics.last_response_tool_calls_suppressed = Some(0);
}
break;
}View on GitHub (pinned to 73e0f67d83)