{"record":{"id":"235bf1b99f285132","repo":"Hmbown/CodeWhale","slug":"task-worker-shutdown-failed-error","errorCode":null,"errorMessage":"Task worker shutdown failed: {error}","messagePattern":"Task worker shutdown failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/task_manager.rs","lineNumber":1569,"sourceCode":"        let _drain = self.shutdown_drain.lock().await;\n        if let Some(runtime) = &self.runtime_threads {\n            runtime.close_execution_admission().await;\n        }\n        // Waiting through the admission fence settles requests that passed\n        // their admission check before shutdown was requested.\n        {\n            let _transaction = self.lock_store().await?;\n        }\n        let mut failure = None;\n        {\n            let mut workers = self.workers.lock().await;\n            while let Some(worker) = workers.last_mut() {\n                // Await by reference: canceling this caller leaves the join in\n                // the manager, so a later drain still waits for actual exit.\n                let result = worker.await;\n                workers.pop();\n                if let Err(error) = result {\n                    failure = Some(anyhow!(\"Task worker shutdown failed: {error}\"));\n                }\n            }\n        }\n        if let Some(runtime) = &self.runtime_threads {\n            runtime.shutdown_and_wait().await?;\n        }\n        failure.map_or(Ok(()), Err)\n    }\n\n    pub(crate) fn execution_scope(&self) -> &str {\n        &self.execution_lease.scope\n    }\n\n    pub(crate) fn session_store_binding(\n        &self,\n    ) -> Option<crate::runtime_threads::RuntimeStoreBinding> {\n        self.runtime_threads\n            .as_ref()","sourceCodeStart":1551,"sourceCodeEnd":1587,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/task_manager.rs#L1551-L1587","documentation":"During task-manager shutdown, each spawned worker task's JoinHandle is awaited; if any worker task panicked or otherwise returned a JoinError, the manager records it and returns 'Task worker shutdown failed: {error}' after draining remaining workers so their exits are still observed.","triggerScenarios":"A worker task panicked or was canceled during shutdown; awaiting the JoinHandle returns Err(JoinError), which the drain loop converts into this anyhow error.","commonSituations":"A panic inside a background task (bug in task handling code); cancellation racing task completion; shutdown while a task is mid-operation on poisoned state.","solutions":["Read the wrapped JoinError/panic message to find the panicking worker task","Fix the underlying panic in the task body","Update/rebuild if the panic comes from a known fixed bug","Retry shutdown after normalizing state; check logs for the first panicking task"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match manager.shutdown().await {\n    Ok(()) => /* done */,\n    Err(e) if e.to_string().starts_with(\"Task worker shutdown failed\") => {\n        log::error!(\"{e:#}\"); // inspect JoinError/panic source, fix task body\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Avoid panics in worker task bodies; return Result instead","Keep worker loops responsive to cancellation","Check logs for the first panicking task to find the root cause"],"tags":["async","tokio","shutdown","panic"],"backgroundTag":"thread-interrupted","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T06:17:15.046Z"}