{"record":{"id":"7f6f5497db4e5a0f","repo":"Hmbown/CodeWhale","slug":"no-engine-installed-for-thread-id","errorCode":null,"errorMessage":"no engine installed for {thread_id}","messagePattern":"no engine installed for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":8193,"sourceCode":"                );\n            }\n        }\n        Ok(())\n    }\n\n    /// Test seam: mark or clear an active turn on an installed test engine so\n    /// route-level tests can exercise restore admission.\n    #[cfg(test)]\n    pub(crate) async fn set_active_turn_for_test(\n        &self,\n        thread_id: &str,\n        turn_id: Option<&str>,\n    ) -> Result<()> {\n        let mut active = self.active.lock().await;\n        let state = active\n            .engines\n            .get_mut(thread_id)\n            .ok_or_else(|| anyhow!(\"no engine installed for {thread_id}\"))?;\n        state.active_turn = turn_id.map(|turn_id| ActiveTurnState {\n            turn_id: turn_id.to_string(),\n            goal_id: None,\n            interrupt_requested: false,\n            compaction_id: None,\n        });\n        Ok(())\n    }\n\n    /// Bind full-fidelity saved history to the exact prefix it covers. Callers\n    /// hold session_checkpoint_guard across the snapshot, save and this write.\n    pub(crate) async fn set_thread_session_checkpoint(\n        &self,\n        thread_id: &str,\n        session: &crate::session_manager::SavedSession,\n    ) -> Result<()> {\n        let session_id = &session.metadata.id;\n        let messages_sha256 = session_messages_sha256(&session.messages)?;","sourceCodeStart":8175,"sourceCodeEnd":8211,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_threads.rs#L8175-L8211","documentation":"Setting a turn's active state requires an engine already installed for the thread in the RuntimeThreadManager's active map. If active.engines has no entry for thread_id, the lookup fails with anyhow!(\"no engine installed for {thread_id}\"). It is an internal sequencing error: the engine must be spawned/registered for a thread before turn operations target it.","triggerScenarios":"Calling the turn-state setter (active_turn update) with a thread_id that has no engine in active.engines — e.g. referencing a thread before its engine was installed, after the engine was removed/cleaned up, or after a shutdown removed engines.","commonSituations":"A stale turn_id/thread_id from a previous session being replayed; racing shutdown while a turn op is still queued; a bug where engine installation failed earlier and the error was swallowed.","solutions":["Ensure the engine for thread_id is installed (spawned via the manager) before starting or interrupting turns","Check earlier logs for a swallowed engine-installation failure for this thread","Re-create/reinstall the thread's engine if it was torn down","Validate the thread_id — it may come from a stale or foreign session"],"exampleFix":"// before\nmanager.set_active_turn(&thread_id, Some(&turn_id)).await?; // engine may not exist\n// after\nif manager.has_engine(&thread_id).await {\n    manager.set_active_turn(&thread_id, Some(&turn_id)).await?;\n} else {\n    manager.install_engine(&thread_id).await?;\n    manager.set_active_turn(&thread_id, Some(&turn_id)).await?;\n}","handlingStrategy":"type-guard","validationCode":"let has_engine = manager.active.lock().await.engines.contains_key(thread_id);\nif !has_engine { bail!(\"engine not installed for {thread_id}; install it first\"); }","typeGuard":"async fn engine_installed(manager: &RuntimeThreadManager, thread_id: &str) -> bool {\n    manager.active.lock().await.engines.contains_key(thread_id)\n}","tryCatchPattern":"match manager.set_active_turn(thread_id, turn).await {\n    Err(e) if e.to_string().starts_with(\"no engine installed\") => {\n        manager.install_engine(thread_id).await?;\n        manager.set_active_turn(thread_id, turn).await?;\n    }\n    other => other?,\n}","preventionTips":["Always install the engine for a thread before any turn op","Do not hold stale thread_ids across sessions; re-derive from the store","Route turn ops through the manager so missing-engine errors surface once at install time"],"tags":["engine","thread","lifecycle"],"backgroundTag":"entity-not-found","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}