Hmbown/CodeWhale · error

agent should stay registered

Error message

agent should stay registered

What it means

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.

Solutions

  1. Ensure SubAgentManager retains results for Interrupted agents (no eviction on interruption)
  2. Compare the agent_id used at dispatch with the one queried in the test
  3. Check get_result's filtering logic hasn't started excluding non-terminal/Interrupted records
  4. Dump manager keys on failure to see whether the id exists under another form

Example fix

// before
.expect("agent should stay registered")
// after
.unwrap_or_else(|| panic!("agent {agent_id} missing; registered={:?}", manager.list_agents()))
Defensive patterns

Strategy: type-guard

Type guard

fn is_registered(manager: &SubAgentManager, id: &str) -> bool {
    manager.get_result(id).is_some()
}

Try / catch

let result = manager.get_result(&agent_id)
    .unwrap_or_else(|| panic!("agent {agent_id} evicted after interruption"));

Prevention

When it happens

Trigger: 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.

Common situations: Cleanup-on-completion refactors removing Interrupted agents from the map; agent_id mismatch (e.g., cloned/reformatted id); get_result filtering by status.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/c6027337c3cd5227. Report an issue: GitHub.

Appendix: source

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

        interrupted_envelope.1
    );

    tokio::time::timeout(Duration::from_secs(5), task_handle)
        .await
        .expect("sub-agent task must not park waiting for checkpoint input")
        .expect("sub-agent task should finish");
    assert_eq!(
        calls.load(Ordering::SeqCst),
        SUBAGENT_API_TIMEOUT_MAX_RETRIES.saturating_add(1) as usize,
        "needs-input interruption must not park for continuation; the API call \
         is retried up to the timeout-retry budget, then stops"
    );

    let interrupted = {
        let manager = manager.read().await;
        manager
            .get_result(&agent_id)
            .expect("agent should stay registered")
    };
    assert!(matches!(interrupted.status, SubAgentStatus::Interrupted(_)));
    let checkpoint = interrupted
        .checkpoint
        .as_ref()
        .expect("timeout should preserve checkpoint");
    assert_eq!(checkpoint.reason, "api_timeout");
    assert!(checkpoint.continuable);
    assert_eq!(checkpoint.steps_taken, 1);
    assert!(
        checkpoint
            .messages
            .iter()
            .any(|message| message_text(message).contains("Inspect checkpoint behavior")),
        "checkpoint should preserve local child prompt: {checkpoint:?}"
    );
    assert!(interrupted.needs_input.is_some());

View on GitHub (pinned to 433685b202)