{"record":{"id":"c6027337c3cd5227","repo":"Hmbown/CodeWhale","slug":"agent-should-stay-registered","errorCode":null,"errorMessage":"agent should stay registered","messagePattern":"agent should stay registered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":9028,"sourceCode":"        interrupted_envelope.1\n    );\n\n    tokio::time::timeout(Duration::from_secs(5), task_handle)\n        .await\n        .expect(\"sub-agent task must not park waiting for checkpoint input\")\n        .expect(\"sub-agent task should finish\");\n    assert_eq!(\n        calls.load(Ordering::SeqCst),\n        SUBAGENT_API_TIMEOUT_MAX_RETRIES.saturating_add(1) as usize,\n        \"needs-input interruption must not park for continuation; the API call \\\n         is retried up to the timeout-retry budget, then stops\"\n    );\n\n    let interrupted = {\n        let manager = manager.read().await;\n        manager\n            .get_result(&agent_id)\n            .expect(\"agent should stay registered\")\n    };\n    assert!(matches!(interrupted.status, SubAgentStatus::Interrupted(_)));\n    let checkpoint = interrupted\n        .checkpoint\n        .as_ref()\n        .expect(\"timeout should preserve checkpoint\");\n    assert_eq!(checkpoint.reason, \"api_timeout\");\n    assert!(checkpoint.continuable);\n    assert_eq!(checkpoint.steps_taken, 1);\n    assert!(\n        checkpoint\n            .messages\n            .iter()\n            .any(|message| message_text(message).contains(\"Inspect checkpoint behavior\")),\n        \"checkpoint should preserve local child prompt: {checkpoint:?}\"\n    );\n    assert!(interrupted.needs_input.is_some());\n","sourceCodeStart":9010,"sourceCodeEnd":9046,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tools/subagent/tests.rs#L9010-L9046","documentation":"Panic from `.expect(\"agent should stay registered\")` on `manager.get_result(&agent_id)`: the SubAgentManager has no stored result for the agent after the API-timeout run. The test requires the manager to keep the Interrupted record rather than evicting the agent when its task ends in an interrupted state.","triggerScenarios":"get_result returns None because the manager removed the agent on task completion/interruption, the agent_id string differs from the one registered, or results are stored only for Completed status.","commonSituations":"Cleanup-on-completion refactors removing Interrupted agents from the map; agent_id mismatch (e.g., cloned/reformatted id); get_result filtering by status.","solutions":["Ensure SubAgentManager retains results for Interrupted agents (no eviction on interruption)","Compare the agent_id used at dispatch with the one queried in the test","Check get_result's filtering logic hasn't started excluding non-terminal/Interrupted records","Dump manager keys on failure to see whether the id exists under another form"],"exampleFix":"// before\n.expect(\"agent should stay registered\")\n// after\n.unwrap_or_else(|| panic!(\"agent {agent_id} missing; registered={:?}\", manager.list_agents()))","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_registered(manager: &SubAgentManager, id: &str) -> bool {\n    manager.get_result(id).is_some()\n}","tryCatchPattern":"let result = manager.get_result(&agent_id)\n    .unwrap_or_else(|| panic!(\"agent {agent_id} evicted after interruption\"));","preventionTips":["Treat Interrupted as a retainable terminal state in the results map","Use one shared constant for agent ids in dispatch and lookup","Add diagnostics (key listing) to not-found assertions"],"tags":["rust","subagent","state-management"],"backgroundTag":"record-not-found","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}