anthropics / anthropics/claude-code

[Bug] Agent teams: separate-process teammates honour a plugin agent's restricted `tools:`, so they can never SendMessage a report back

Open
#81,185 1 comment 0 reactions 0 assignees View on GitHub
area:agents area:plugins
Dominant language
Python
Stars
145k
Forks
23.1k
PR merge metrics
PR metrics pending

Description

### Summary

A teammate's only channel for returning a result is `SendMessage`. When a teammate's `--agent-type` resolves to a **plugin** agent whose frontmatter declares a restricted `tools:` list, that list is honoured — and because it contains neither `SendMessage` nor `ToolSearch`, the teammate completes its work and has **no way to deliver it**. It goes idle and the lead receives a contentless `idle_notification`. Nothing errors, so the failure is invisible from both sides.

### Evidence — controlled comparison, same session and launch path

| `--agent-type` | tools declared | report delivered? |
|---|---|---|
| `feature-dev:code-reviewer` (×5) | no `SendMessage` / no `ToolSearch` | ❌ 0 / 5 |
| `general-purpose` (×3) | `*` | ✅ 3 / 3 |

Only the agent type differed. Asked to enumerate its own tools, a `feature-dev:code-reviewer` teammate replied:

> I have access to these tools in this session: `Read`, `WebFetch`, `WebSearch`, `TaskStop`, `TaskOutput`, `Glob`, `Grep`. I don't have `SendMessage` or `ToolSearch` — I can't message teammates or search for additional tools.

Another wrote its finished report into its final assistant message with the note:

> Note: The `SendMessage` tool isn't available in this session, so I'm delivering the report directly here.

The work existed in every case; only delivery was impossible. Recovering it required reading each agent's `.jsonl` transcript out of band. A stale inbox at `~/.claude/teams//inboxes/.json` still holds 2 undelivered inbound messages for one such agent.

### Why `ToolSearch` matters too

Per the analysis in #68408, `SendMessage` is a **deferred** tool: its schema must be loaded via `ToolSearch("select:SendMessage")` before it can be invoked. An agent whose `tools:` list omits **both** therefore has no recovery path — it cannot even discover the tool.

### This appears to be backend-dependent

#78234 reports that for **in-process** teammates, plugin-scoped subagent definitions are silently *dropped* (the teammate spawns with `tools: ["*"]`). We observe the **opposite** for teammates spawned as **separate `claude` processes**: the plugin definition *is* applied, restricted tool list included. If both observations hold, teammate tool resolution differs by backend, and only the separate-process path is affected by this bug.

### Also observed: the tool list has drifted

The plugin declares `Glob, Grep, LS, Read, NotebookRead, WebFetch, TodoWrite, WebSearch, KillShell, BashOutput`, but the teammate actually reports `Read, WebFetch, WebSearch, TaskStop, TaskOutput, Glob, Grep` — `LS`, `NotebookRead` and `TodoWrite` resolve to nothing, and `KillShell`/`BashOutput` surface as `TaskStop`/`TaskOutput`. Unrelated to the delivery bug, but it suggests plugin agent definitions aren't validated against the current tool registry.

### Expected

Any one of:

1. **Always grant team-coordination tools** (`SendMessage`, and `ToolSearch` while `SendMessage` remains deferred) to teammates regardless of the definition's `tools:` list. The agent-teams docs already imply coordination tools are always available to a teammate.
2. **Make `SendMessage` non-deferred** so it needs no `ToolSearch` to invoke (also suggested in #68408).
3. **Fail loudly at spawn** if a teammate's resolved toolset cannot reach `SendMessage`, instead of silently producing an agent that can never report.

### Repro

1. `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`, teammates spawned as separate `claude` processes into tmux panes.
2. Spawn a teammate with `--agent-type feature-dev:code-reviewer` (any plugin agent with a restricted `tools:` list) and instruct it to `SendMessage` its result to the lead.
3. It performs the work, then goes idle. The lead receives only a bare `idle_notification` with no content. The report is present in the agent's transcript.
4. Repeat with `--agent-type general-purpose` → delivery succeeds.

### Note on setup

Our teammates are launched into panes managed by a local IDE that provides a **shim `tmux` on `PATH`** and intercepts tmux commands, rather than genuine tmux. The shim only handles pane creation/teardown — `--agent-type` resolution and tool assignment happen inside the real spawned `claude` process (launched with `--agent-id/--agent-name/--team-name/--agent-type/--settings`). Flagging it for reproducibility, since it may or may not be relevant.

### Environment

- Claude Code 2.1.219
- macOS
- `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`
- Plugin: `feature-dev@claude-plugins-official`, `gitCommitSha` `96276205880a60fd66bbae981f5ab568e70c4cbf`

### Related

- #68408 — `SendMessage` advertised but unavailable / deferred-schema problem
- #74113 — background agents go idle without delivering their final `SendMessage` report
- #78234 — plugin-scoped subagent definitions silently ignored in agent teams (in-process path)
- #80569 — teammates ignore `effort` frontmatter from subagent definitions

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by running the separate-process repro with --agent-type feature-dev:code-reviewer and general-purpose, comparing resolved tools and report delivery through SendMessage and ToolSearch. Trace tool assignment during the spawned claude process and verify that a restricted teammate can deliver its report or fails loudly at spawn instead of producing only an idle_notification.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai-infra-agents, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.