{"record":{"id":"c4981557be20dfd9","repo":"Hmbown/CodeWhale","slug":"thread-already-has-an-active-turn","errorCode":null,"errorMessage":"Thread already has an active turn","messagePattern":"Thread already has an active turn","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":5933,"sourceCode":"                    req.permission_posture.as_deref(),\n                    req.auto_approve,\n                )?\n            } else {\n                RuntimePolicyProjection::from_persisted(\n                    &thread.mode,\n                    thread.permission_posture.as_deref(),\n                    thread.auto_approve,\n                )\n            };\n        let mode = policy.mode;\n        let engine = self.ensure_engine_loaded(&thread).await?;\n\n        let client_preflight_required = {\n            let active = self.active.lock().await;\n            if let Some(active_thread) = active.engines.get(thread_id)\n                && active_thread.active_turn.is_some()\n            {\n                bail!(\"Thread already has an active turn\");\n            }\n            active\n                .engines\n                .get(thread_id)\n                .is_none_or(|state| state.client_preflight_required)\n        };\n\n        // Resolve the concrete provider/model before persisting a turn. Auto\n        // routing can fail, and such a failure must not leave a zombie\n        // in-progress record behind.\n        let requested_model = req.model.as_deref().unwrap_or(&thread.model).to_string();\n        let auto_model = requested_model.trim().eq_ignore_ascii_case(\"auto\");\n        let cfg_snapshot = self.config.read().clone();\n        let identity = self.provider_identity_for_thread(&cfg_snapshot, &thread)?;\n        let mut thread_config = cfg_snapshot.clone();\n        thread_config.scope_to_provider_identity(&identity);\n        let verbosity = thread_config.verbosity.clone();\n        let reasoning_preference = thread_config","sourceCodeStart":5915,"sourceCodeEnd":5951,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/runtime_threads.rs#L5915-L5951","documentation":"start_turn's engine preflight found the thread already has an active turn. Threads execute one turn at a time; this fires when a second concurrent start (or a steering race) arrives before the first turn completes.","triggerScenarios":"Thrown at crates/tui/src/runtime_threads.rs:5933 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Wait for the active turn to finish","Or interrupt it before starting a new one"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}