Hmbown/CodeWhale · error · anyhow::Error
Agent session not found
Error message
Agent session {agent_ref} not found What it means
The subagent tool resolves an agent reference (`agent_ref`, which may be a name or an agent_id) to exactly one agent session by collecting matching agent IDs. This error is thrown when the reference matches zero sessions, meaning the caller named an agent that does not exist in the current session's agent table.
Solutions
- Re-list available agents to get a valid agent_id and use that exact id
- Check whether the subagent already completed or was cancelled; start a new one if needed
- Fix the agent_ref spelling/whitespace and retry
- Verify the agent was spawned in the same active session, not a prior session
Example fix
// before
let id = resolve("my-agnt")?; // Err: Agent session my-agnt not found
// after
let agents = list_agents();
let id = agents.iter().find(|a| a.id == "my-agent").map(|a| a.id.clone()).ok_or_else(|| anyhow!("spawn agent first"))?; Defensive patterns
Strategy: validation
Validate before calling
fn ensure_agent_exists(agents: &[AgentInfo], agent_ref: &str) -> Result<&AgentInfo, String> {
agents.iter().find(|a| a.id == agent_ref || a.name == agent_ref)
.ok_or_else(|| format!("agent '{agent_ref}' not found; available: {:?}", agents.iter().map(|a| a.id.as_str()).collect::<Vec<_>>()))
} Type guard
fn is_known_agent(agents: &[AgentInfo], agent_ref: &str) -> bool {
agents.iter().any(|a| a.id == agent_ref || a.name == agent_ref)
} Try / catch
match resolve_agent_ref(agent_ref) {
Ok(id) => proceed(id),
Err(e) if e.to_string().contains("not found") => refresh_agent_list_and_retry(),
Err(e) => return Err(e),
} Prevention
- Always address subagents by their unique agent_id, not a display name
- Capture the agent_id returned at spawn time and reuse it
- Re-list agents before acting if time has passed since spawn
When it happens
Trigger: Calling a subagent coordination tool (e.g. agent send/interrupt/status) with an `agent_ref` string that does not match any live SubAgent id or name, or referencing an agent whose session already terminated and was reaped.
Common situations: A typo in the agent name; using a stale agent_id captured before the agent finished; a subagent completing or crashing between listing agents and acting on one; passing a name that was never registered because the spawn failed.
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
- Agent continuation target is no longer retained
- Agent continuation target is outside the active session
- Agent not found
- Agent session name ' ' is ambiguous; use an agent_id
- agent should stay registered
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ce53f9d20de413b8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:7518
.is_none_or(|session_id| self.agent_is_owned_by_session(agent, session_id))
})
.collect::<Vec<_>>();
// A reused name shadows settled holders: the live worker wins, and
// settled records stay id-addressable (#6313).
if matches
.iter()
.any(|agent| !subagent_status_is_settled(&agent.status))
{
matches.retain(|agent| !subagent_status_is_settled(&agent.status));
}
let matches = matches
.iter()
.map(|agent| agent.id.clone())
.collect::<Vec<_>>();
match matches.as_slice() {
[id] => Ok(id.clone()),
[] => Err(anyhow!("Agent session {agent_ref} not found")),
_ => Err(anyhow!(
"Agent session name '{agent_ref}' is ambiguous; use an agent_id"
)),
}
}
fn agent_is_owned_by_session(&self, agent: &SubAgent, active_session_id: &str) -> bool {
!active_session_id.is_empty() && agent.owner_session_id == active_session_id
}
fn agent_id_is_owned_by_session(&self, agent_id: &str, active_session_id: &str) -> bool {
self.agents
.get(agent_id)
.is_some_and(|agent| self.agent_is_owned_by_session(agent, active_session_id))
}
/// Resolve a hierarchy mutation target and prove that it is a strict
/// descendant of the calling agent. Root registries carry no caller idView on GitHub (pinned to 73e0f67d83)