{"record":{"id":"e3f1a5b2b4b46c42","repo":"Hmbown/CodeWhale","slug":"terminal-snapshot-remains","errorCode":null,"errorMessage":"terminal snapshot remains","messagePattern":"terminal snapshot remains","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":6808,"sourceCode":"        manager.current_session_boot_id.clone(),\n    );\n    manager.agents.insert(agent_id.clone(), agent);\n    manager.register_worker(make_worker_spec(&agent_id, tmp.path().to_path_buf()));\n\n    manager.cancel_agent(&agent_id).expect(\"cancel wins race\");\n    let mut late = manager\n        .get_result(&agent_id)\n        .expect(\"cancelled snapshot exists\");\n    late.status = SubAgentStatus::Completed;\n    late.result = Some(\"late success\".to_string());\n    assert!(\n        !manager.update_from_result(&agent_id, late),\n        \"late completion must lose the terminal transition\"\n    );\n\n    let snapshot = manager\n        .get_result(&agent_id)\n        .expect(\"terminal snapshot remains\");\n    assert_eq!(snapshot.status, SubAgentStatus::Cancelled);\n    assert_eq!(\n        snapshot.result.as_deref(),\n        Some(\"Cancelled by parent request.\")\n    );\n    let record = manager\n        .get_worker_record(&agent_id)\n        .expect(\"worker record remains\");\n    let terminal = record\n        .events\n        .iter()\n        .filter(|event| event.status.is_terminal())\n        .collect::<Vec<_>>();\n    assert_eq!(terminal.len(), 1);\n    assert_eq!(terminal[0].status, AgentWorkerStatus::Cancelled);\n}\n\n#[tokio::test]","sourceCodeStart":6790,"sourceCodeEnd":6826,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/tests.rs#L6790-L6826","documentation":"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.","triggerScenarios":"After `update_from_result` rejects a late Completed result, reading the snapshot when the rejection path incorrectly removed or invalidated the stored terminal snapshot.","commonSituations":"Regression where update_from_result takes the entry out of the map before deciding to reject it.","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."],"exampleFix":"// before: entry taken then rejected, snapshot lost\nlet entry = self.results.remove(id);\n// after: inspect before mutating\nif existing.status.is_terminal() { return false; }","handlingStrategy":"type-guard","validationCode":"// guard before mutating stored results\nfn is_terminal(s: &SubAgentStatus) -> bool {\n    matches!(s, SubAgentStatus::Cancelled | SubAgentStatus::Completed | SubAgentStatus::Failed)\n}","typeGuard":"fn terminal_snapshot(r: &Option<SubAgentResult>) -> Option<&SubAgentResult> {\n    r.as_ref().filter(|s| matches!(s.status, SubAgentStatus::Cancelled))\n}","tryCatchPattern":"let snapshot = manager.get_result(&agent_id)\n    .unwrap_or_else(|| panic!(\"terminal snapshot vanished for {agent_id}\"));","preventionTips":["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"],"tags":["test-assertion","terminal-state","subagent","race-condition"],"backgroundTag":"internal-invariant-violation","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"}