Hmbown/CodeWhale · error

Agent not found

Error message

Agent {agent_id} not found

What it means

cancel_agent first resolves the caller-supplied agent reference to an agent ID, then looks the ID up in the in-memory agent map. If no live (tracked) agent matches, the cancel cannot proceed and the library throws this not-found error, naming the resolved agent_id.

Solutions

  1. List the currently tracked agents first and cancel using a ref from that list.
  2. Check whether the agent already finished; a completed agent needs no cancellation.
  3. Re-run the sub-agent spawn if the intent was to restart it, then cancel the new ref.
  4. Verify the ref/ID spelling and that you are in the same session that spawned the agent.

Example fix

// before: cancelling a possibly-finished agent blindly
manager.cancel_agent("agent-7")?;
// after: check liveness first
if manager.list_agents().iter().any(|a| a.id == "agent-7") {
    manager.cancel_agent("agent-7")?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn can_cancel(mgr: &SubAgentManager, agent_ref: &str) -> bool {
    mgr.resolve_agent_ref(agent_ref).ok()
        .map(|id| mgr.find_agent(&id).is_some())
        .unwrap_or(false)
}

Type guard

fn live_agent<'a>(mgr: &'a SubAgentManager, agent_ref: &str) -> Option<&'a SubAgent> {
    let id = mgr.resolve_agent_ref(agent_ref).ok()?;
    mgr.find_agent(&id)
}

Try / catch

match manager.cancel_agent(agent_ref) {
    Err(e) if e.to_string().contains("not found") => info!("agent already finished"),
    r => r?,
}

Prevention

When it happens

Trigger: Calling cancel_agent(ref) with a reference to an agent that has already terminated and been reaped, was never spawned in this session, or whose ID was mistyped/aliased.

Common situations: Cancelling after the sub-agent already completed and its record was cleared; using an agent ref from a previous session after state restore; a stale UI handle to a finished agent.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/tools/subagent/mod.rs:5671

                .checkpoint
                .as_ref()
                .is_some_and(|checkpoint| checkpoint.parked_at_turn_end);
            match &result.status {
                SubAgentStatus::Failed(err) => record.error = Some(err.clone()),
                SubAgentStatus::BudgetExhausted => record.error = message.clone(),
                _ => {}
            }
        }
        self.record_worker_event(worker_id, status, message, Some(result.steps_taken), None);
    }

    pub fn cancel_agent(&mut self, agent_ref: &str) -> Result<SubAgentResult> {
        let agent_id = self.resolve_agent_ref(agent_ref)?;
        let mut terminal = {
            let agent = self
                .agents
                .get(&agent_id)
                .ok_or_else(|| anyhow!("Agent {agent_id} not found"))?;
            if agent.status != SubAgentStatus::Running {
                let snapshot = self.snapshot_for_listing(agent);
                return Ok(self.terminalize_settled_worker_on_cancel(&agent_id, snapshot));
            }
            if agent.completion_claimed {
                // Still running, with its terminal transition already claimed:
                // mid-flight, not settled. Stealing it here would record a
                // second terminal outcome for one child.
                return Ok(self.snapshot_for_listing(agent));
            }
            self.snapshot_for_listing(agent)
        };
        terminal.status = SubAgentStatus::Cancelled;
        terminal.result = Some("Cancelled by parent request.".to_string());
        terminal.needs_input = None;
        if !self.finish_terminal_result(&agent_id, terminal, true, true) {
            return self.get_result(&agent_id);
        }

View on GitHub (pinned to 73e0f67d83)