{"record":{"id":"175c1a797906a33e","repo":"Hmbown/CodeWhale","slug":"runtime-is-shutting-down-execution-admission-is-closed","errorCode":null,"errorMessage":"Runtime is shutting down; execution admission is closed","messagePattern":"Runtime is shutting down; execution admission is closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":5256,"sourceCode":"        }\n        self.engine_workers\n            .lock()\n            .retain(|(_, worker)| !completion_finished(worker));\n        let mut active = self.active.lock().await;\n        active.engines.clear();\n        active.lru.clear();\n        failure.map_or(Ok(()), Err)\n    }\n\n    fn track_receipt_worker(&self, worker: tokio::task::JoinHandle<()>) {\n        let mut monitors = self.turn_monitors.lock();\n        monitors.retain(|monitor| !completion_finished(monitor));\n        monitors.push(retained_completion(worker));\n    }\n\n    fn ensure_accepting_execution(&self) -> Result<()> {\n        if self.cancel_token.is_cancelled() {\n            bail!(\"Runtime is shutting down; execution admission is closed\");\n        }\n        Ok(())\n    }\n\n    /// Runtime clones retained by live Engine/tool work retain this lease too.\n    /// A TaskManager cancellation timeout cannot release execution ownership.\n    pub(crate) fn retain_task_execution_lease(\n        &self,\n        lease: Arc<crate::task_manager::TaskExecutionLease>,\n    ) -> Result<()> {\n        let mut current = self.task_execution_lease.lock();\n        if current.is_some() {\n            bail!(\"This Runtime already owns a task execution manager\");\n        }\n        *current = Some(lease);\n        Ok(())\n    }\n","sourceCodeStart":5238,"sourceCodeEnd":5274,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_threads.rs#L5238-L5274","documentation":"ensure_accepting_execution refuses new execution admissions once the Runtime's cancellation token is cancelled, i.e. during shutdown. This prevents work from being enqueued into a Runtime that is tearing down.","triggerScenarios":"Submitting a turn, tool call, or other execution to a Runtime whose shutdown has begun (cancel_token cancelled).","commonSituations":"Firing a background task that races Runtime shutdown; automation scripts submitting work while the app is quitting; long-lived handle used after drop of the main session.","solutions":["Stop submitting work once shutdown is initiated; await Runtime completion instead","Re-create a new Runtime instance if you need to continue executing work","Check the cancellation/shutdown state before admitting work in your orchestration code"],"exampleFix":"// before\nruntime.submit_turn(turn).await;\n// after\nif !runtime.is_shutting_down() {\n    runtime.submit_turn(turn).await;\n}","handlingStrategy":"try-catch","validationCode":"if runtime.is_cancelled() { /* skip submission */ }","typeGuard":null,"tryCatchPattern":"match runtime.submit_work(task) {\n    Err(e) if e.to_string().contains(\"execution admission is closed\") => {\n        // runtime is shutting down; drop or reschedule on a new runtime\n    }\n    other => other?,\n}","preventionTips":["Track runtime shutdown state in your orchestration layer","Avoid fire-and-forget submissions that can outlive the session","Use a CancellationToken-aware scheduler"],"tags":["shutdown","lifecycle","concurrency"],"backgroundTag":"invalid-state-transition","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"}