Hmbown/CodeWhale · error · anyhow::Error
Agent session name ' ' is ambiguous; use an agent_id
Error message
Agent session name '{agent_ref}' is ambiguous; use an agent_id What it means
When resolving an `agent_ref` by name, more than one agent session matches, so the tool cannot pick one unambiguously. The library refuses to guess and asks the caller to use the unique `agent_id` instead of the human-readable name.
Solutions
- Use the agent's unique agent_id instead of its name in the tool call
- Give each subagent a unique name at spawn time
- List all agents to see which ids share the name and pick the intended one
Example fix
// before
agent_send("worker", "continue"); // ambiguous: 3 agents named worker
// after
agent_send("a1f3-worker-uuid", "continue"); // use agent_id Defensive patterns
Strategy: validation
Validate before calling
fn ensure_unique_name(agents: &[AgentInfo], name: &str) -> Result<&AgentInfo, String> {
let matches: Vec<_> = agents.iter().filter(|a| a.name == name).collect();
match matches.len() { 1 => Ok(matches[0]), 0 => Err(format!("no agent named {name}")), _ => Err(format!("{name} is ambiguous; use agent_id")) }
} Type guard
fn resolves_uniquely(agents: &[AgentInfo], name: &str) -> bool {
agents.iter().filter(|a| a.name == name).count() == 1
} Try / catch
match resolve_agent_ref(name_ref) {
Ok(id) => proceed(id),
Err(e) if e.to_string().contains("ambiguous") => list_agents().iter().filter(|a| a.name == name_ref).map(|a| a.id.clone()).collect::<Vec<_>>(), // prompt user to pick
Err(e) => return Err(e),
} Prevention
- Give each subagent a unique name at spawn time (e.g. suffix with a counter or uuid)
- Prefer agent_id over name in all coordination tool calls
- Treat names as labels only, never as identifiers
When it happens
Trigger: Invoking a subagent coordination tool with a shared agent name (e.g. "worker") after spawning multiple subagents with that same name; reusing a default agent name across several spawns.
Common situations: Spawning several parallel worker subagents without unique names, then sending a message or command addressed to the shared name.
Related errors
- Agent continuation target is no longer retained
- Agent continuation target is outside the active session
- Agent not found
- Agent session not found
- agent should stay registered
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/7a4881174dcc72c2.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:7519
})
.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 id
/// (or the literal `root`) and retain authority over every child. ThisView on GitHub (pinned to 73e0f67d83)