Hmbown/CodeWhale · error
image inputs require an exact named model with supported…
Error message
image inputs require an exact named model with supported image input; Auto is unavailable for images
What it means
Codewhale's runtime turn handler refuses to start a turn that includes image (attachment) blocks unless the request names a concrete model. The special model value "auto" (and empty/whitespace-padded names) trigger dynamic model routing, which cannot guarantee image-input capability, so it is rejected up front with this error.
Solutions
- Set req.model to an exact named model that supports image input (capabilities.image_input == Supported).
- Remove the image blocks from the request if Auto routing is required.
- Check the resolved route's capabilities via resolve_runtime_thread_route_for_identity before sending images.
Example fix
// before
let req = ThreadTurnRequest { model: "auto".into(), prompt: prompt_with_screenshot, ..Default::default() };
// after
let req = ThreadTurnRequest { model: "claude-sonnet-4".into(), prompt: prompt_with_screenshot, ..Default::default() }; Defensive patterns
Strategy: validation
Validate before calling
fn can_send_images(req: &ThreadTurnRequest, thread: &Thread) -> bool {
let model = req.model.as_deref().unwrap_or(&thread.model).trim();
!model.is_empty() && !model.eq_ignore_ascii_case("auto")
} Type guard
fn is_exact_model(model: &str) -> bool { !model.trim().is_empty() && !model.trim().eq_ignore_ascii_case("auto") } Prevention
- Never send attachments while the model picker is on Auto.
- Resolve the effective model before constructing the request.
- Check the route's image_input capability when enabling image upload UI.
When it happens
Trigger: Calling the runtime turn API (ThreadTurnRequest) with a prompt containing image content blocks while req.model (or the thread's model) is set to "auto" (case-insensitive).
Common situations: Developers leaving the model selector on Auto/default while pasting a screenshot into the chat; programmatic clients omitting `model` when sending attachments; UI code that resolves "auto" to a routing placeholder before dispatch.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- maxOutputTokens requires an exact model; Auto routing is…
- 1
- A pinned task provider requires an explicit model
- A positive pull request number is required
- A provider and page loader are required.
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/412afb378af61890.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:9861
req.mode.as_deref(),
req.permission_posture.as_deref(),
req.auto_approve,
)?
} else {
RuntimePolicyProjection::from_persisted(
&thread.mode,
thread.permission_posture.as_deref(),
thread.auto_approve,
)
};
let mode = policy.mode;
let requested_model = req.model.as_deref().unwrap_or(&thread.model).to_string();
let auto_model = requested_model.trim().eq_ignore_ascii_case("auto");
if !image_blocks.is_empty() && (requested_model.is_empty() || requested_model.trim() != requested_model) {
bail!("image inputs require an exact nonempty named model");
}
if !image_blocks.is_empty() && auto_model {
bail!("image inputs require an exact named model with supported image input; Auto is unavailable for images");
}
let cfg_snapshot = self.config.read().clone();
let configured_reasoning_preference = cfg_snapshot
.reasoning_effort()
.map(crate::reasoning_preference::ReasoningEffort::from_setting);
// Runtime API precedence is explicit and stable: a turn override wins
// over its persisted thread default, which wins over normal config.
let reasoning_preference = turn_reasoning_preference
.or(thread_reasoning_preference)
.or(configured_reasoning_preference);
let allow_shell = req.allow_shell.unwrap_or(thread.allow_shell);
let trust_mode = req.trust_mode.unwrap_or(thread.trust_mode);
let auto_approve = policy.auto_approve();
let allowed_tools = req
.allowed_tools
.clone()
.or_else(|| thread.allowed_tools.clone());
if req.max_output_tokens.is_some() && auto_model {View on GitHub (pinned to 73e0f67d83)