Hmbown/CodeWhale · warning

first coordination interrupt

Error message

first coordination interrupt

What it means

Test assertion `...interrupt_child(&agent_id, Some("agent_parent"), reason.clone()).expect("first coordination interrupt")` at `crates/tui/src/tools/subagent/tests.rs:6705`. The test interrupts a Running child agent from its parent and expects the call to succeed, returning the prior state (Running) and the interrupt record. A panic means interrupt_child returned Err for the first, legitimate interrupt.

Solutions

  1. Surface the actual Err (unwrap_or_else including it in the panic) to see why the interrupt was refused.
  2. Verify the agent is registered and in Running state on the same manager before interrupt_child is called.
  3. Check any parent-id validation in interrupt_child: the test's 'agent_parent' must be accepted for a Worker-role child in tests.
  4. Confirm the prior.status assertion expectation (Running) still matches the state machine; update the test if the transition contract legitimately changed.

Example fix

// before
let (prior, first) = manager
    .interrupt_child(&agent_id, Some("agent_parent"), reason.clone())
    .expect("first coordination interrupt");
// after
let (prior, first) = manager
    .interrupt_child(&agent_id, Some("agent_parent"), reason.clone())
    .unwrap_or_else(|e| panic!("first coordination interrupt of {agent_id} failed: {e:?}"));
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the child is Running and registered before interrupting:
let rec = manager.get_worker_record(&agent_id).expect("child registered");
assert_eq!(rec.status, AgentWorkerStatus::Running, "child must be Running before interrupt");

Try / catch

let (prior, first) = manager.interrupt_child(&agent_id, Some("agent_parent"), reason.clone())
    .unwrap_or_else(|e| panic!("first coordination interrupt failed: {e:?}"));

Prevention

When it happens

Trigger: interrupt_child errors because the agent is not registered with this manager, the agent id mismatches, the parent id 'agent_parent' is rejected by a new parentage check, or a state-machine change makes Running non-interruptible or requires a different role.

Common situations: Refactors adding parentage/permission validation to interrupt_child that break the test's synthetic parent id; state machine changes that remove or rename the Running->interrupted transition; test setup reordered so the agent is not yet Running when interrupted.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/9fefd6cdffc949a4. Report an issue: GitHub.

Appendix: source

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

    for caller in ["agent_missing", "agent_unrelated", agent_id.as_str()] {
        assert!(
            manager
                .interrupt_child(&agent_id, Some(caller), "forbidden".into())
                .is_err()
        );
    }
    manager.record_worker_event(
        &agent_id,
        AgentWorkerStatus::RunningTool,
        Some("step 2/8: running tool 'read_file'".to_string()),
        Some(2),
        Some("read_file".to_string()),
    );

    let reason = "parent rerouted this lane".to_string();
    let (prior, first) = manager
        .interrupt_child(&agent_id, Some("agent_parent"), reason.clone())
        .expect("first coordination interrupt");
    let (_, second) = manager
        .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

View on GitHub (pinned to 73e0f67d83)