Hmbown/CodeWhale · warning
Runtime is shutting down; execution admission is closed
Error message
Runtime is shutting down; execution admission is closed
What it means
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.
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
Example fix
// before
runtime.submit_turn(turn).await;
// after
if !runtime.is_shutting_down() {
runtime.submit_turn(turn).await;
} Defensive patterns
Strategy: try-catch
Validate before calling
if runtime.is_cancelled() { /* skip submission */ } Try / catch
match runtime.submit_work(task) {
Err(e) if e.to_string().contains("execution admission is closed") => {
// runtime is shutting down; drop or reschedule on a new runtime
}
other => other?,
} Prevention
- Track runtime shutdown state in your orchestration layer
- Avoid fire-and-forget submissions that can outlive the session
- Use a CancellationToken-aware scheduler
When it happens
Trigger: Submitting a turn, tool call, or other execution to a Runtime whose shutdown has begun (cancel_token cancelled).
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Pet recorder is closed or already writing.
- Task manager is shutting down; admission is closed
- Wait for the pet recorder write before closing.
- A saved trace identifier collided. Try saving again.
- a window change is already in progress
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/175c1a797906a33e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:5256
}
self.engine_workers
.lock()
.retain(|(_, worker)| !completion_finished(worker));
let mut active = self.active.lock().await;
active.engines.clear();
active.lru.clear();
failure.map_or(Ok(()), Err)
}
fn track_receipt_worker(&self, worker: tokio::task::JoinHandle<()>) {
let mut monitors = self.turn_monitors.lock();
monitors.retain(|monitor| !completion_finished(monitor));
monitors.push(retained_completion(worker));
}
fn ensure_accepting_execution(&self) -> Result<()> {
if self.cancel_token.is_cancelled() {
bail!("Runtime is shutting down; execution admission is closed");
}
Ok(())
}
/// Runtime clones retained by live Engine/tool work retain this lease too.
/// A TaskManager cancellation timeout cannot release execution ownership.
pub(crate) fn retain_task_execution_lease(
&self,
lease: Arc<crate::task_manager::TaskExecutionLease>,
) -> Result<()> {
let mut current = self.task_execution_lease.lock();
if current.is_some() {
bail!("This Runtime already owns a task execution manager");
}
*current = Some(lease);
Ok(())
}
View on GitHub (pinned to 73e0f67d83)