{"record":{"id":"7ff901d7741b77ec","repo":"Hmbown/CodeWhale","slug":"turn-lifecycle-task-ended-before-acknowledgement","errorCode":null,"errorMessage":"Turn lifecycle task ended before acknowledgement","messagePattern":"Turn lifecycle task ended before acknowledgement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":10328,"sourceCode":"                policy.permission,\n                configured_sandbox_mode,\n            );\n            engine.send_reserved_op(permit, op);\n            if let Some(settlement) = initial_routed_usage_settlement.as_mut() {\n                settlement.disarm();\n            }\n            touch_lru(&mut active.lru, thread_id);\n            self.spawn_claimed_turn_monitor(\n                turn.clone(),\n                Some(user_item),\n                engine.clone(),\n                ClaimedTurnKind::Message,\n            )\n        };\n\n        let turn = acceptance_rx\n            .await\n            .map_err(|_| anyhow!(\"Turn lifecycle task ended before acknowledgement\"))?\n            .map_err(anyhow::Error::msg)?;\n        Ok((turn, false))\n        })\n        .await\n    }\n\n    pub async fn interrupt_turn(&self, thread_id: &str, turn_id: &str) -> Result<TurnRecord> {\n        {\n            let mut active = self.active.lock().await;\n            let Some(active_thread) = active.engines.get_mut(thread_id) else {\n                bail!(\"Thread is not loaded\");\n            };\n            let Some(active_turn) = active_thread.active_turn.as_mut() else {\n                bail!(\"No active turn on thread {thread_id}\");\n            };\n            if active_turn.turn_id != turn_id {\n                bail!(\"Turn {turn_id} is not active on thread {thread_id}\");\n            }","sourceCodeStart":10310,"sourceCodeEnd":10346,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_threads.rs#L10310-L10346","documentation":"Raised when the oneshot channel that carries the turn's acceptance acknowledgement is dropped before a value arrives, meaning the spawned turn-lifecycle task ended (panicked, was aborted, or exited early) without ever accepting or rejecting the prepared turn. The runtime converts the RecvError into this anyhow error instead of hanging forever.","triggerScenarios":"Awaiting `acceptance_rx` after spawning the claimed-turn monitor; the sender side is dropped because the lifecycle task panicked or was cancelled before sending the turn record through.","commonSituations":"A panic inside the engine turn task (bug or OOM kill); the Tokio runtime shutting down while a turn is being submitted; the lifecycle task being aborted by engine teardown during thread unload or app exit.","solutions":["Check the application logs/stderr for a panic in the turn lifecycle task around the time of this error.","Retry the turn — the store is consistent, so a fresh submission is safe.","If it reproduces, ensure the Tokio runtime is not being shut down (or the task aborted) while turns are in flight.","Report as a bug if reproducible: the lifecycle task should always send an acceptance or a rejection."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match send_turn(prompt) {\n    Err(e) if e.to_string().contains(\"ended before acknowledgement\") => {\n        // check logs for lifecycle-task panic, then resubmit the turn once\n    }\n    r => r?,\n}","preventionTips":["Keep the Tokio runtime alive for the duration of in-flight turns.","Watch logs for panics in turn lifecycle tasks and fix root causes promptly.","Avoid force-killing the app while turns are being submitted.","Ensure adequate memory so worker tasks are not OOM-killed."],"tags":["async","channel-closed","task-panic","rust"],"backgroundTag":"unexpected-response-shape","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"}