[Bug] Agent-team teammates ignore effort frontmatter from subagent definitions

Status Open
Reported on v2.1.218
Maintainer reply None cached
Activity 3 comments · opened Jul 23, 2026

Bug Description
Agent-team teammates silently ignore the effort frontmatter from their subagent definition

effort is a documented, supported subagent frontmatter field (sub-agents doc: "Effort level when this subagent is active. Overrides the session effort level."). It works when the definition runs as a plain subagent via the Agent/Task tool.

But when the same definition is spawned as a teammate in an experimental agent team (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1), the effort field is silently dropped — the teammate inherits the lead's session effort instead. No warning is shown. The agent-teams doc says teammates honor a definition's tools and model and explicitly lists skills/mcpServers as not applied, but never mentions effort, so this is both a behavior gap and a doc gap.

This defeats the main reason to use agent teams for delegation: routing tasks to different models and effort tiers. model crosses over correctly; effort does not. The only workaround is manually /effort-ing each teammate after spawn, which isn't declarative and doesn't scale.

Repro:

  1. Define ~/.claude/agents/planner.md with model: opus, effort: max.
  2. Run the lead session at a low effort (e.g. /effort low).
  3. Spawn a teammate from the planner definition.
  4. Observed: teammate runs at the lead's low effort. Expected: max from its frontmatter (as it would as a plain subagent).

Ask: either honor effort on the teammate path (consistent with model), or if intentional, document it as unsupported like skills/mcpServers and warn on spawn. Related closed issues: #25591, #65598, #30703 and https://github.com/anthropics/claude-code/issues/64706

Environment Info

  • Platform: linux
  • Terminal: windows-terminal
  • Version: 2.1.218
  • Feedback ID: 18f10718-9b33-4da8-9eaf-3e5c1bca9f42

View original on GitHub ↗

3 Comments

coljnr9 · 28 days ago

Claude Code CLI, version 2.1.220

# ~/.claude/settings.json:
"env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" },
"teammateMode": "tmux"
  • Define a subagent with explicit effort: high.
  • Start a session Claude Code CLI session and set effort to medium
/effort medium 
  • In the main session, prompt to spawn a test subagent:

 ▐▛███▜▌   Claude Code v2.1.220
▝▜█████▛▘  Opus 5 with medium effort · Claude Max
  ▘▘ ▝▝    ~/llm-workspace/terminus-v2


❯ Please spawn a named subagent using the Agent tool. Use the implementer subagent type.  Simply ask it to respond to "ping", this is simply a subagent test.

● I'll spawn a named implementer subagent.

● implementer(Subagent ping test)

● Spawned ping-test (implementer). Waiting on its reply.
  • Observe the header in the spawned session, verify with the /effort command.

Expected

Subagent spawns with effort defined in agent definition frontmatter (i.e. high)

Actual

Subagent spawns with parent's effort level (in this case, medium)


 ▐▛███▜▌   Claude Code v2.1.220
▝▜█████▛▘  Sonnet 5 with medium effort · Claude Max 
  ▘▘ ▝▝    @implementer · ~/llm-workspace/terminus-v2



› Message from @team-lead

● pong

✻ Sautéed for 4s

(modal from /effort)
                Faster                                                 Smarter
                ──────────▲────────────────────────────────┆──────────────────
                low     medium     high     xhigh      max       ultracode
                                                             xhigh + workflows

File: ~/.claude/agents/implementer.md

---
name: implementer
description: Executes spec-conforming changes needing low or moderate judgment. 
model: sonnet
effort: high
tools: Read, Grep, Glob, Edit, Write, Bash, SendMessage, LSP, ToolSearch
---

Role: ...
guyoron · 27 days ago

Corroborating this from local transcript data - same version (v2.1.220, macOS), CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" at user scope.

I looked at ~400 subagent transcripts under ~/.claude/projects/*/<session>/subagents/*.jsonl, comparing each agent's recorded effort against its parent session's effort at spawn time. The split falls exactly on whether the spawn passed name:

| Spawn | Runs | Used the definition's effort |
|---|---|---|
| With name: (teammate path) | 88 | 0 |
| Without name: | 191 | 19 |

The 88 named runs took the parent session's effort in every case, including ones where the definition clearly said otherwise:

Worth noting alongside #77655 that the subagent detail view reliably showed the parent session's info (eg "Opus 5 with high effort") transcripts recorded conflicting info (eg claude-fable-5). So that surface, the only one I can easily find to inspect the subagent's info, reports incorrect info.

rajavemuri · 14 days ago

Still reproduces on 2.1.233 (Linux, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" at user scope, in-process teammate mode). Adding a controlled probe and a workaround that hasn't been mentioned in this thread.

Controlled probe — same definition, two spawns, only name: differs

~/.claude/agents/executor-scout.md declares model: sonnet, effort: high. Lead session at xhigh:

| Spawn | taskKind | Recorded effort |
|---|---|---|
| Agent({subagent_type: "executor-scout", prompt}) | null | high ✅ definition |
| Agent({subagent_type: "executor-scout", name: "probe", prompt}) | in_process_teammate | xhigh ❌ lead's |

Confirmed the other direction too: executor-sonnet (declared effort: xhigh) spawned with a name from a lead running at high recorded high. So the teammate takes the lead's effort in both directions — the definition is not clamped, it's discarded.

A useful detail for anyone reproducing: on the teammate path meta.json overwrites agentType with the agent's name and moves the real type to customAgentType. It looks like the wrong agent type was requested when it wasn't:

{"agentType":"regen-impl","customAgentType":"executor-sonnet","name":"regen-impl","taskKind":"in_process_teammate","model":"sonnet"}

The silent-promotion direction is the expensive one

The reports so far are about teammates running below their declared effort, which shows up as weak output. The reverse is costlier and invisible: a cheap recon agent declared at high, spawned with a name from an xhigh lead, runs at xhigh. Nothing looks broken — you just pay top-tier effort for mechanical file reading, which is the entire reason that tier declares a lower effort. Across my transcripts this was the common case, since recon agents get named for legibility.

Workaround: omit name: — it costs less than it appears

name: is what selects the teammate path, so dropping it restores the pin. That's per-call rather than global, so you keep agent teams everywhere else.

The reason this is cheap: an unnamed agent is still addressable. It returns an ID that SendMessage accepts, and follow-ups work with context intact — I have unnamed agents in my transcripts that ran 24, 63, 75, and 482 turns via SendMessage to their hex ID. So the keep-an-agent-alive pattern survives; what you actually give up is the readable @name label in the transcript, and possibly mid-flight messaging (name: is documented as making an agent addressable while running, whereas the ID route is documented for continuing a previously spawned one — I did not test interrupting an unnamed agent mid-task).

For anyone considering the bigger hammer: setting CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=0 also restores the pin (verified — name: is then silently ignored and the spawn is a plain task), and cross-session peer discovery via ListAgents/SendMessage still works with it off. But every name: becomes a no-op, so any workflow built on named teammates goes with it. Omitting name: selectively is strictly better.

Ask

Honoring effort: on the teammate path, consistent with model:, is the right fix. Failing that, the cheapest useful change is a warning at spawn time when a definition declares an effort: that the teammate path is about to discard — the whole problem is that it's silent, and both failure directions are easy to run for weeks without noticing.