{"record":{"id":"1eb53d648f663465","repo":"Hmbown/CodeWhale","slug":"parent-cancellation-fan-in","errorCode":null,"errorMessage":"parent cancellation fan-in","messagePattern":"parent cancellation fan-in","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/tools/subagent/tests.rs","lineNumber":6601,"sourceCode":"        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\n        .drain()\n        .into_iter()\n        .filter(|envelope| {\n            matches!(\n                envelope.message,\n                MailboxMessage::Completed { .. }\n                    | MailboxMessage::Failed { .. }\n                    | MailboxMessage::Interrupted { .. }\n                    | MailboxMessage::Cancelled { .. }\n            )\n        })\n        .collect::<Vec<_>>();\n    assert_eq!(terminal_mail.len(), 1);\n    assert!(matches!(","sourceCodeStart":6583,"sourceCodeEnd":6619,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/tests.rs#L6583-L6619","documentation":"Test assertion `completion_rx.try_recv().expect(\"parent cancellation fan-in\")` at `crates/tui/src/tools/subagent/tests.rs:6601`. The test expects that when a parent cancels a child agent, exactly one completion event is fanned into the completion channel. A panic here means no completion event was delivered at all (try_recv returned Empty/Disconnected) — the cancellation did not propagate to the completion fan-in path.","triggerScenarios":"The cancel path never emits the AgentComplete event: e.g. the cancellation token is not observed by the agent's wait loop, the completion sender was dropped before the cancel, or a refactor routes completion through a different channel/mailbox than the one this test drains.","commonSituations":"Changes to SubAgentManager's cancellation plumbing (token wiring, mailbox draining, fan-in dedup) that drop the terminal completion event; tests flaking if cancellation races event delivery — though try_recv after awaits should be deterministic if fan-in happens before return.","solutions":["Replace try_recv with a bounded recv (with timeout) in a debug run to distinguish 'no event ever' from 'not yet delivered' (race).","Trace the cancel_agent path and confirm it sends an AgentComplete with cancelled status into the completion channel exactly once.","Check the parent-child cancellation token wiring: interrupt/cancel must trigger the agent's terminal transition that emits the event.","If a dedup/fan-in guard was added recently, ensure it drops duplicates, not the first event."],"exampleFix":"// before\nlet completion = completion_rx.try_recv().expect(\"parent cancellation fan-in\");\n// after\nlet completion = tokio::time::timeout(std::time::Duration::from_secs(5), completion_rx.recv())\n    .await\n    .expect(\"timed out waiting for parent cancellation fan-in\")\n    .expect(\"completion channel closed before fan-in event\");","handlingStrategy":"try-catch","validationCode":"// Replace bare try_recv with a bounded await in tests:\nlet completion = tokio::time::timeout(Duration::from_secs(5), completion_rx.recv()).await;\nassert!(matches!(completion, Ok(Some(_))), \"expected exactly one fan-in completion\");","typeGuard":null,"tryCatchPattern":"let completion = timeout(Duration::from_secs(5), completion_rx.recv()).await\n    .expect(\"fan-in event never arrived (timeout)\")\n    .expect(\"completion sender dropped before fan-in\");","preventionTips":["Never assert on channels with bare try_recv in async tests; use bounded recv.","Keep the completion sender alive until the terminal transition completes.","Guard fan-in dedup logic so it drops duplicates, never the first event."],"tags":["rust","test","panic","cancellation","async","channel"],"backgroundTag":"unexpected-response-shape","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T06:17:15.046Z"}