{"record":{"id":"7a38629112bb27a5","repo":"Hmbown/CodeWhale","slug":"first-stop","errorCode":null,"errorMessage":"first Stop","messagePattern":"first Stop","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":6587,"sourceCode":"\n    let (completion_tx, mut completion_rx) = mpsc::channel::<SubAgentCompletion>(16);\n    let (mailbox, mut mailbox_rx) = Mailbox::new(CancellationToken::new());\n    let (event_tx, mut event_rx) = mpsc::channel(8);\n    let mut runtime = runtime_with_depth(1, Some(completion_tx));\n    runtime.mailbox = Some(mailbox);\n    runtime.event_tx = Some(event_tx);\n    agent.terminal_delivery = Some(SubAgentTerminalDeliveryContext::from_runtime(&runtime));\n    manager.agents.insert(agent_id.clone(), agent);\n    manager.register_worker(make_worker_spec(&agent_id, tmp.path().to_path_buf()));\n    manager.record_worker_event(\n        &agent_id,\n        AgentWorkerStatus::ModelWait,\n        Some(SUBAGENT_MODEL_WAIT_REASON.to_string()),\n        Some(1),\n        None,\n    );\n\n    let first = manager.cancel_agent(&agent_id).expect(\"first Stop\");\n    let second = manager.cancel_agent(&agent_id).expect(\"repeated Stop\");\n    assert_eq!(first.status, SubAgentStatus::Cancelled);\n    assert_eq!(second.status, SubAgentStatus::Cancelled);\n    assert_eq!(\n        first\n            .checkpoint\n            .as_ref()\n            .map(|checkpoint| checkpoint.reason.as_str()),\n        Some(\"test_checkpoint\")\n    );\n\n    let completion = completion_rx\n        .try_recv()\n        .expect(\"parent cancellation fan-in\");\n    assert!(completion.payload.contains(r#\"\"status\":\"cancelled\"\"#));\n    assert!(completion_rx.try_recv().is_err());\n\n    let terminal_mail = mailbox_rx","sourceCodeStart":6569,"sourceCodeEnd":6605,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/tests.rs#L6569-L6605","documentation":"Test assertion `manager.cancel_agent(&agent_id).expect(\"first Stop\")` in the model-wait-cancel fan-in test at `crates/tui/src/tools/subagent/tests.rs:6587`. The test puts an agent into ModelWait state and issues the first Stop/cancel; the expect asserts cancellation of a live agent succeeds and returns its termination record. A panic here means the manager refused or failed the first cancel.","triggerScenarios":"`cancel_agent` returns Err for an agent it should know about — e.g. the agent was never registered with this manager (wrong SubAgentManager instance or tmp path), the id string 'agent_model_wait_cancel' mismatches, or a change to cancel_agent makes ModelWait a non-cancellable state.","commonSituations":"Refactors of the subagent state machine (adding states, gating cancellation by status) that forget ModelWait; test setup reordering so the manager is constructed with a different store dir than the agent was registered under.","solutions":["Print the cancel_agent error (replace expect with a descriptive panic including the Err) to see why the first Stop was rejected.","Verify the agent was registered with the same manager and id used in cancel_agent.","Check cancel_agent's state gating: ModelWait agents must remain cancellable; fix the state machine if it now returns an error for ModelWait.","Re-run with the unmodified test to confirm it is a regression from a recent commit (git blame the cancel path)."],"exampleFix":"// before\nlet first = manager.cancel_agent(&agent_id).expect(\"first Stop\");\n// after\nlet first = manager.cancel_agent(&agent_id)\n    .unwrap_or_else(|e| panic!(\"first Stop of {agent_id} failed: {e:?}\"));","handlingStrategy":"type-guard","validationCode":"// Before cancelling, confirm the agent is known and cancellable:\nassert!(manager.get_worker_record(&agent_id).is_some(), \"agent must be registered before first Stop\");","typeGuard":null,"tryCatchPattern":"let first = manager.cancel_agent(&agent_id).unwrap_or_else(|e| panic!(\"first Stop failed: {e:?}\"));","preventionTips":["Keep ModelWait and all non-terminal states cancellable in cancel_agent's gating.","Assert registration before lifecycle calls in tests.","Include the error payload in lifecycle-assertion panic messages."],"tags":["rust","test","panic","cancellation","subagent"],"backgroundTag":"invalid-state-transition","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}