Hmbown/CodeWhale · error
Failed to trigger compaction: engine operation channel…
Error message
Failed to trigger compaction: engine operation channel closed
What it means
Raised when reserving a slot on the engine's operation channel (`tx_op.reserve_owned()`) fails while triggering a compaction, which can only happen if the channel is closed — i.e. the engine task has already terminated. Without a reserved permit the runtime cannot hand the Op::CompactContext operation to the engine, so it fails fast with this error instead of hanging.
Solutions
- Retry compaction — `ensure_engine_loaded` will respawn a fresh engine if the old one died.
- Check logs for an engine task panic and address its root cause.
- Avoid triggering compaction during application shutdown.
- If it reproduces on one thread, unload/reload that thread to rebuild its engine.
Defensive patterns
Strategy: retry
Try / catch
match runtime.compact_thread(&thread_id, req).await {
Err(e) if e.to_string().contains("operation channel closed") => {
// engine died: reload thread / respawn engine, then retry compaction once
}
r => r?,
} Prevention
- Fix engine worker panics reported in logs before retrying heavy operations.
- Do not request compaction during application shutdown.
- Reload threads whose engines have been idle-evicted.
- Monitor engine worker health (worker completions are retained in runtime state).
When it happens
Trigger: Calling `compact_thread` when the thread's engine worker task has exited (panicked, aborted during shutdown, or completed) so `engine.tx_op` is closed and `reserve_owned().await` returns Err.
Common situations: The engine worker crashed earlier (check logs for panics); the app is shutting down while compaction is requested; the thread's engine was reaped (LRU eviction/cleanup) between `ensure_engine_loaded` and the reserve.
Related errors
- Compaction lifecycle task ended before acknowledgement
- Failed to sync thread session
- engine event channel closed before turn
- Runtime engine shutdown failed
- Turn lifecycle task ended before acknowledgement
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/636e29ece4c5c450.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:10609
&route_model,
)),
routed_usage: Vec::new(),
routed_usage_drop_records: Vec::new(),
routed_usage_source_ids: Vec::new(),
routed_usage_dropped_records: 0,
model_request_diagnostics: None,
error: None,
item_ids: Vec::new(),
steer_count: 0,
agent_mail_message_id: None,
};
let op = Op::CompactContext {
id: compaction_id.clone(),
route: Box::new(route),
compaction: Box::new(compaction),
};
let permit = engine.tx_op.clone().reserve_owned().await.map_err(|_| {
anyhow!("Failed to trigger compaction: engine operation channel closed")
})?;
let acceptance_rx = {
let mut active = self.active.lock().await;
let Some(state) = active.engines.get_mut(thread_id) else {
bail!("Thread engine not loaded");
};
if state.active_turn.is_some() {
bail!("Thread already has an active turn");
}
let _thread_mutation = self.store.thread_mutation.lock();
let mut current_thread = self.store.load_thread(thread_id)?;
if !thread_execution_state_matches(&thread, ¤t_thread) {
bail!("Thread execution settings changed while preparing compaction; retry");
}
let previous_active_route = (state.route_identity.clone(), state.route_model.clone());
state.active_turn = Some(ActiveTurnState {
goal_id: None,View on GitHub (pinned to 73e0f67d83)