Hmbown/CodeWhale · error
terminal snapshot remains
Error message
terminal snapshot remains
What it means
Test panic: the second `get_result` call after a rejected late-completion update returned None, failing `.expect("terminal snapshot remains")`. The invariant is that a failed `update_from_result` must not mutate or remove the existing Cancelled snapshot.
Solutions
- Make update_from_result reject terminal overrides without touching the stored snapshot (check status first, then clone).
- Verify get_result does not consume (take) the entry on read.
- Run the race test and confirm snapshot.status remains Cancelled with the original message.
Example fix
// before: entry taken then rejected, snapshot lost
let entry = self.results.remove(id);
// after: inspect before mutating
if existing.status.is_terminal() { return false; } Defensive patterns
Strategy: type-guard
Validate before calling
// guard before mutating stored results
fn is_terminal(s: &SubAgentStatus) -> bool {
matches!(s, SubAgentStatus::Cancelled | SubAgentStatus::Completed | SubAgentStatus::Failed)
} Type guard
fn terminal_snapshot(r: &Option<SubAgentResult>) -> Option<&SubAgentResult> {
r.as_ref().filter(|s| matches!(s.status, SubAgentStatus::Cancelled))
} Try / catch
let snapshot = manager.get_result(&agent_id)
.unwrap_or_else(|| panic!("terminal snapshot vanished for {agent_id}")); Prevention
- Reject update_from_result for terminal snapshots before any mutation
- Avoid Option::take/HashMap::remove on read paths; clone instead
- Cover the late-completion-loses race with a test on every result-path change
When it happens
Trigger: After `update_from_result` rejects a late Completed result, reading the snapshot when the rejection path incorrectly removed or invalidated the stored terminal snapshot.
Common situations: Regression where update_from_result takes the entry out of the map before deciding to reject it.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- cancel wins race
- worker record remains
- cancelled snapshot exists
- parent interruption fan-in
- parent turn is already settling foreground work as
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e3f1a5b2b4b46c42.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:6808
manager.current_session_boot_id.clone(),
);
manager.agents.insert(agent_id.clone(), agent);
manager.register_worker(make_worker_spec(&agent_id, tmp.path().to_path_buf()));
manager.cancel_agent(&agent_id).expect("cancel wins race");
let mut late = manager
.get_result(&agent_id)
.expect("cancelled snapshot exists");
late.status = SubAgentStatus::Completed;
late.result = Some("late success".to_string());
assert!(
!manager.update_from_result(&agent_id, late),
"late completion must lose the terminal transition"
);
let snapshot = manager
.get_result(&agent_id)
.expect("terminal snapshot remains");
assert_eq!(snapshot.status, SubAgentStatus::Cancelled);
assert_eq!(
snapshot.result.as_deref(),
Some("Cancelled by parent request.")
);
let record = manager
.get_worker_record(&agent_id)
.expect("worker record remains");
let terminal = record
.events
.iter()
.filter(|event| event.status.is_terminal())
.collect::<Vec<_>>();
assert_eq!(terminal.len(), 1);
assert_eq!(terminal[0].status, AgentWorkerStatus::Cancelled);
}
#[tokio::test]View on GitHub (pinned to 73e0f67d83)