Hmbown/CodeWhale · error
image inputs require a model with explicitly supported…
Error message
image inputs require a model with explicitly supported image input
What it means
Even with an exact model named, the runtime validates the resolved route's capabilities and fails the turn if the selected model's route does not declare image_input as CapabilityState::Supported. This is the capability check after routing, complementing the Auto-model checks.
Solutions
- Switch to a model whose route declares CapabilityState::Supported for image_input.
- Remove the image attachments from the turn.
- Fix the provider/route config so the intended model exposes image_input: supported.
Example fix
// before req.model = "text-only-model".into(); req.prompt = blocks_with_image; // after req.model = "gpt-4o".into(); // image_input: Supported req.prompt = blocks_with_image;
Defensive patterns
Strategy: validation
Validate before calling
let route = resolve_runtime_thread_route_for_identity(&cfg, &identity, Some(&model))?; assert_eq!(route.candidate.capabilities().image_input, CapabilityState::Supported, "model cannot accept images");
Type guard
fn supports_images(cap: &CapabilityState) -> bool { *cap == CapabilityState::Supported } Prevention
- Gate the attach-image UI on the resolved route's image_input capability.
- Re-validate capabilities after any provider/route config change.
- Keep a list of known vision-capable models per provider.
When it happens
Trigger: Sending image_blocks with an exact model whose resolved route candidate reports image_input != Supported (e.g. a text-only model like an o1-mini-style or small local model).
Common situations: Pointing the thread at a text-only model and attaching a screenshot; provider config drift where a model was previously multimodal; routing tables listing a model under a provider that strips vision support.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Choose a model for the destination provider before…
- image inputs require an exact named model with supported…
- maxOutputTokens is unsupported by the selected provider…
- MCP server ' ': initialize capabilities must be an object
- Runtime image input is unavailable; update the Runtime…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ec8d7717840ded74.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:9917
self.prepare_runtime_turn_operation(
thread_id,
Some(operation_key),
request_fingerprint,
reserved_turn_id,
)?
} else {
None
};
if let Some(operation) = operation.as_ref()
&& let Some(original_turn) = self.replay_turn_for_operation(operation)?
{
return Ok((original_turn, true));
}
if !image_blocks.is_empty() || req.max_output_tokens.is_some() {
let identity = self.provider_identity_for_thread(&cfg_snapshot, &thread)?;
let route = resolve_runtime_thread_route_for_identity(&cfg_snapshot, &identity, Some(&requested_model))?;
if !image_blocks.is_empty() && route.candidate.capabilities().image_input != codewhale_config::route::CapabilityState::Supported {
bail!("image inputs require a model with explicitly supported image input");
}
if req.max_output_tokens.is_some() && !crate::route_budget::route_supports_output_token_limit(route.identity.provider, route.candidate.protocol()) {
bail!("maxOutputTokens is unsupported by the selected provider transport");
}
}
let engine = self.ensure_engine_loaded(&thread).await?;
let client_preflight_required = {
let active = self.active.lock().await;
if let Some(active_thread) = active.engines.get(thread_id)
&& active_thread.active_turn.is_some()
{
bail!("Thread already has an active turn");
}
active
.engines
.get(thread_id)
.is_none_or(|state| state.client_preflight_required)View on GitHub (pinned to 73e0f67d83)