Hmbown/CodeWhale · error
model client should be configured
Error message
model client should be configured
What it means
consult_auto_review_guardian() unwraps access to the turn's model client, asserting the turn loop only reaches this point after the client was configured. Hitting the expect means a turn was started without a model client — an engine state-machine bug, not user input.
Source
Thrown at crates/tui/src/core/engine/turn_loop.rs:563
&mut self,
turn: &mut TurnContext,
tool_policy: ToolSurfacePolicy,
// Out-of-request facts resolved once for this turn. `None` means the
// caller captured none, and the projection reports every
// registry-derived field as unknown rather than guessing.
inspection_surface: Option<crate::tool_inspection::ToolSurfaceContext>,
) -> (TurnOutcomeStatus, Option<String>) {
// Only interactive TUI hosts own terminal chrome. Headless exec,
// app-server, and stream-json stdout must remain byte-clean.
if self.config.terminal_chrome_enabled {
crate::tui::notifications::set_taskbar_progress_busy();
crate::tui::notifications::start_title_animation("Codewhale");
}
let client = self
.model_client
.clone()
.expect("model client should be configured");
let mut turn_error: Option<String> = None;
// Cleared when the loop continues only for optional runtime work
// (a goal continuation) after the model already delivered an answer.
let mut step_budget_exhaustion_is_terminal = true;
let mut context_recovery_attempts = 0u8;
let mut tool_policy = tool_policy;
let mut mode = tool_policy.mode;
let mut questions_allowed = tool_policy.allows_questions();
let strict_tool_mode = tool_policy.strict_tool_mode;
let mut tool_catalog = std::mem::take(&mut tool_policy.catalog);
let mut active_tool_names = std::mem::take(&mut tool_policy.active_names);
// Search activations belong to the conversation, not just the user
// turn. Revalidate names against this turn's already-filtered catalog
// before exposing them; stale mode/MCP/allow-list entries disappear.
let evicted = self.session.tool_activation_cache.revalidate(&tool_catalog);
super::tool_catalog::remove_evicted_cache_activations(
&tool_catalog,View on GitHub (pinned to 0c42157ee5)
Solutions
- Ensure the turn is aborted earlier when no model client is configured
- Trace how run_turn was reached with an unset client and fix the guard upstream
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at crates/tui/src/core/engine/turn_loop.rs:563 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/d02ed84d0551c7e4.
Report an issue: GitHub.