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

  1. Use the agent's unique agent_id instead of its name in the tool call
  2. Give each subagent a unique name at spawn time
  3. 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

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


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. This

View on GitHub (pinned to 73e0f67d83)