Hmbown/CodeWhale · warning · anyhow::Error
auto-route classifier response incomplete: provider stop rea
Error message
auto-route classifier response incomplete: provider stop reason `{}` What it means
The auto-route feature asks a model to classify which model should serve a request. The provider's stop_reason was flagged by is_incomplete_stop_reason() (crates/tui/src/models.rs): output-limit reasons (length/max_tokens/max_output_tokens), 'incomplete:*', content_filter, or model_context_window_exceeded. A truncated recommendation cannot be trusted, so the classifier errors; the call itself is bounded by a 4-second timeout.
Source
Thrown at crates/tui/src/model_routing.rs:1041
.clone()
.unwrap_or_else(|| "off".to_string()),
),
stream: Some(false),
temperature: None,
top_p: None,
};
let response = if allow_response_cache {
tokio::time::timeout(Duration::from_secs(4), client.create_message(request)).await??
} else {
tokio::time::timeout(
Duration::from_secs(4),
client.create_message_without_response_cache(request),
)
.await??
};
if crate::models::is_incomplete_stop_reason(response.stop_reason.as_deref()) {
anyhow::bail!(
"auto-route classifier response incomplete: provider stop reason `{}`",
crate::models::stop_reason_detail(response.stop_reason.as_deref())
);
}
Ok(parse_inventory_auto_route_recommendation(
&message_response_text(&response),
inventory,
))
}
fn inventory_auto_router_system_prompt(inventory: &ModelInventory, cost_saving: bool) -> String {
let mut prompt = if inventory.cross_provider_auto {
String::new()
} else {
// The inventory JSON below is already scoped to the active provider
// (#4411); say so, so the classifier does not try to name one it was
// never shown.
format!(View on GitHub (pinned to 8880682c63)
Solutions
- Fall back to the default model selection when the classifier errors — that is the intended caller behavior
- Shrink the model inventory the router considers so recommendations fit the output budget
- Raise the classifier model's output token limit if your provider config allows it
- Retry once; transient truncation or filter hits often pass on a second attempt
Example fix
// before: classifier failure propagates
let route = classify_auto_route(&inventory, req).await?;
// after: fall back to the default route
let route = classify_auto_route(&inventory, req)
.await
.unwrap_or_else(|_| inventory.default_route()); Defensive patterns
Strategy: fallback
Type guard
```rust
fn is_incomplete_classifier(err: &anyhow::Error) -> bool {
format!("{err:#}").contains("auto-route classifier response incomplete")
}
``` Try / catch
```rust
let route = match classify_auto_route(&inventory, &request).await {
Ok(route) => route,
Err(e) if is_incomplete_classifier(&e) => inventory.default_route(), // truncation carries no signal
Err(e) => return Err(e),
};
``` Prevention
- Keep the routed model inventory small so recommendations fit the classifier's output budget
- Treat classifier failures as 'use the default route', never as fatal routing errors
- Prefer classifier models with generous output-token limits
When it happens
Trigger: Running the auto-route classifier with a model inventory large enough that the routing recommendation exceeds the classifier model's output-token limit, or the provider ending generation early via content filtering.
Common situations: Huge multi-provider model lists inflating the recommendation; providers with small default output budgets; aggressive safety filters tripping on inventory text.
Related errors
- provider stream error: {error}
- {} model {:?} uses {:?}, but this client is bound to {:?} an
- Model response incomplete: provider stop reason `{}`; the pa
- Model response incomplete: provider stop reason `{}`; the JS
- DeepSeek ${res.status}: ${text}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/3f8302bf02f58e98.
Report an issue: GitHub.