Hmbown/CodeWhale · error

parent interruption fan-in

Error message

parent interruption fan-in

What it means

Test panic from `try_recv().expect(...)`: the completion channel was empty when the test expected the parent-interruption fan-in to have delivered exactly one completion message. It indicates the interrupted child never sent its terminal completion payload on the channel.

Solutions

  1. Verify the interrupt path emits exactly one AgentComplete-style payload containing "status":"interrupted" and the reason.
  2. Check the completion channel is the one wired to the agent under test and is not drained by another consumer.
  3. Add a short await/poll loop instead of an immediate try_recv if the emission is asynchronous.

Example fix

// before
let completion = completion_rx.try_recv().expect("parent interruption fan-in");
// after
let completion = completion_rx.recv().await.expect("parent interruption fan-in");
Defensive patterns

Strategy: retry

Validate before calling

// precheck: channel still open and agent registered
assert!(!completion_rx.is_closed(), "completion channel closed prematurely");

Try / catch

let completion = tokio::time::timeout(Duration::from_secs(2), completion_rx.recv())
    .await
    .expect("timed out")
    .expect("parent interruption fan-in");

Prevention

When it happens

Trigger: After a parent interrupt fans in, awaiting `completion_rx.try_recv()` when the child's completion event was not emitted (or was emitted with the wrong payload, failing the subsequent `contains` assertions).

Common situations: Changes to the subagent event loop dropping the completion emission on interrupt; channel closed or event consumed elsewhere; test racing a spawn that has not yet flushed its terminal event.

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/efaefe8a633ae100. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/subagent/tests.rs:6725

        .interrupt_child(&agent_id, Some("agent_parent"), reason.clone())
        .expect("repeated coordination interrupt");
    assert_eq!(prior.status, SubAgentStatus::Running);
    assert!(matches!(
        first.status,
        SubAgentStatus::Interrupted(ref actual) if actual == &reason
    ));
    assert_eq!(second.status, first.status);
    assert_eq!(
        first
            .checkpoint
            .as_ref()
            .map(|checkpoint| (checkpoint.reason.as_str(), checkpoint.steps_taken)),
        Some(("test_checkpoint", 2))
    );

    let completion = completion_rx
        .try_recv()
        .expect("parent interruption fan-in");
    assert!(completion.payload.contains(r#""status":"interrupted""#));
    assert!(completion.payload.contains(&reason));
    assert!(completion_rx.try_recv().is_err());

    let terminal_mail = mailbox_rx
        .drain()
        .into_iter()
        .filter(|envelope| {
            matches!(
                envelope.message,
                MailboxMessage::Completed { .. }
                    | MailboxMessage::Failed { .. }
                    | MailboxMessage::Interrupted { .. }
                    | MailboxMessage::Cancelled { .. }
            )
        })
        .collect::<Vec<_>>();
    assert_eq!(terminal_mail.len(), 1);

View on GitHub (pinned to 73e0f67d83)