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

  1. Make update_from_result reject terminal overrides without touching the stored snapshot (check status first, then clone).
  2. Verify get_result does not consume (take) the entry on read.
  3. 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

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


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)