[BUG] Agent-teams teammate panes wedged with "<Box> can't be nested inside <Text>" Ink error on 2.1.119 — not reproducible on 2.1.138 (regression record + fix confirmation)

Resolved 💬 1 comment Opened May 10, 2026 by sauravvarma Closed Jun 9, 2026

Bug report — formatted for anthropics/claude-code bug_report.yml

Source: BUG-REPORT.md (preserved). Reshaped after 2026-05-10 reverify on 2.1.138.

---

Title

[BUG] Agent-teams teammate panes wedged with "<Box> can't be nested inside <Text>" Ink error on 2.1.119 — not reproducible on 2.1.138 (regression record + fix confirmation)

Preflight Checklist

  • [x] Searched existing issues — closest matches are #10313 (closed, different Ink CLI crash), #38941 (closed, Yoga/Ink renderer dump), #48670 (open, MCP needs-auth-cache misbehavior — overlaps with the trigger condition here).
  • [x] Single bug report.
  • [x] Latest version — verified on 2.1.138; original evidence on 2.1.119.

What's Wrong?

On Claude Code 2.1.119, agent-teams teammate panes spawned via TeamCreate + Agent({team_name}) deterministically crashed their Ink renderer with <Box> can't be nested inside <Text> component (thrown from cli.js:502:249) the first time a permission prompt rendered while the "N MCP server needs auth · /mcp" footer banner was active. The Claude process and tmux pane stayed alive (pgrep found the PID, tmux list-panes reported dead=0, team config still said isActive: true), but the teammate's message-consume loop wedged behind the dead renderer. The team lead saw indefinite silence — no error, no idle notification, no shutdown_response. Manual tmux kill-pane was the only recovery; TeamDelete then failed until the wedged member was manually removed from ~/.claude/teams/<team>/config.json.

On 2.1.138, the same trigger condition no longer reproduces (see "Additional Information"). I'm filing this anyway because:

  1. The 2.1.119 crash was severe (silent teammate wedge with no signal path) and worth a searchable record in case of regression.
  2. If the fix was intentional, confirming the responsible change/version helps users who hit this on older binaries triage their workaround.
  3. If the non-repro is accidental (e.g. the banner-rendering component got refactored, but the underlying invalid composition still exists in a less-exercised path), it's worth flagging.

What Should Happen?

(a) Teammate renders the permission prompt + footer banner without crashing. (b) Even if a render error occurred, it should propagate to the agent-teams supervisor as an agent_crashed event, not present as indefinite silence with isActive: true.

Error Messages/Logs

From the 2.1.119 wedged teammate pane:

ctx: 6 / 1000000 (2%)
        1 MCP server needs auth · /mcp

  ERROR  <Box> can't be nested inside <Text>
        component

 /$bunfs/root/src/entrypoints/cli.js:502:249

Throwing site (Ink reconciler createInstance, minified from Bun bundle):

createInstance(H,_,q,K,O){
  if(K.isInsideText && H==="ink-box")
    throw Error("<Box> can't be nested inside <Text> component");
  let T = H==="ink-text" && K.isInsideText ? "ink-virtual-text" : H;
  let $ = Yq_(T);
  ...
}

Call stack tail:

- createInstance (/$bunfs/root/src/entrypoints/cli.js:502:249)
- PL             (/$bunfs/root/src/entrypoints/cli.js:484:58456)
- LYH            (/$bunfs/root/src/entrypoints/cli.js:484:88642)
- rZH            (/$bunfs/root/src/entrypoints/cli.js:484:87842)
- RD6            (/$bunfs/root/src/entrypoints/cli.js:484:86738)
- iZH            (/$bunfs/root/src/entrypoints/cli.js:484:86558)
- jM_            (/$bunfs/root/src/entrypoints/cli.js:484:83272)
- aH             (/$bunfs/root/src/entrypoints/cli.js:484:6552)
- LH             (/$bunfs/root/src/entrypoints/cli.js:484:5006)
- FH             (/$bunfs/root/src/entrypoints/cli.js:484:5318)

Names minified (Bun bundle), but line/col offsets are stable for 2.1.119 and should source-map cleanly.

Steps to Reproduce

(Historical — on 2.1.119. Same steps on 2.1.138 do not reproduce; see "Additional Information".)

  1. Ensure at least one MCP server is in needs-auth state:

``bash
cat ~/.claude/mcp-needs-auth-cache.json # must be non-empty
``

  1. From a Claude Code session, create a team and spawn one general-purpose teammate:

``
TeamCreate({ team_name: "repro" })
Agent({
subagent_type: "general-purpose",
team_name: "repro",
name: "worker",
prompt: "Run
ls /tmp/__nope__$$ 2>&1 || echo NOT_FOUND via Bash and reply with the output."
})
``

  1. Wait for the teammate to send a permission_request, then grant it.
  1. Observed on 2.1.119: teammate pane crashes with the Box-in-Text error and freezes; no reply; subsequent SendMessages land in inbox JSON but read stays false forever. Reproduced 4× across two runs with two trigger tools (Bash + Write).

Claude Model

Opus (claude-opus-4-7). Healthy comparison teammate in the same 2.1.119 session used Haiku/Explore and never hit a permission prompt — model was not the variable; the permission-prompt + auth-banner composition was.

Is this a regression?

I don't know. The behavior was new-observation on 2.1.119; not bisected against older versions. (For 2.1.138 the bug appears resolved.)

Last Working Version

N/A — not bisected.

Claude Code Version

Evidence: 2.1.119. Reverify: 2.1.138 (cannot reproduce — see below).

Platform

Anthropic API.

Operating System

macOS (Darwin 25.3.0 / macOS 26.3.1 on the original 2.1.119 host; Darwin 25.4.0 / macOS 26.3.1 on the 2.1.138 reverify host).

Terminal/Shell

Original (2.1.119): iTerm2, agent-teams backend = tmux (socket claude-swarm-18922), teammateMode: "tmux".

Reverify (2.1.138): tested both iTerm2 host (iterm2 backend) and Ghostty host (tmux backend) — neither reproduces.

Additional Information

Reverify on 2.1.138 (2026-05-10)

Same trigger condition (10 MCP servers in ~/.claude/mcp-needs-auth-cache.json, including the same claude.ai connectors that triggered the original crash), same spawn pattern (TeamCreate + general-purpose Agent with team_name), same minimal prompts (single Bash perm prompt; multi-stage Bash + Write + Read perm prompts). Three runs:

| # | Host terminal | Backend (per team config) | Stages | Result |
|---|---|---|---|---|
| 1 | iTerm2 | iterm2 | Bash perm prompt | Worker replied cleanly in ~36s |
| 2 | iTerm2 | iterm2 | Bash + Write + Read perm prompts | All stages clean in ~24s |
| 3 | Ghostty | tmux | Bash + Write + Read perm prompts | All stages clean in ~20s |

Run 3 is the closest match to the 2.1.119 conditions (tmux backend, same trigger). It does not reproduce.

2.1.119 evidence (preserved)

MCP needs-auth state at teammate spawn (original):

$ cat ~/.claude/mcp-needs-auth-cache.json
{"claude.ai Gmail":      {"timestamp":1777220169909},
 "claude.ai Google Drive":{"timestamp":1777220169912},
 "claude.ai Google Calendar":{"timestamp":1777220169922}}

All three timestamps = 2026-04-26 16:16:09 UTC, ~4 seconds before the wedged teammate spawned.

Round-by-round (2.1.119):

| Round | Spawn time | MCP needs-auth | Outcome |
|---|---|---|---|
| R1 (gp-alpha, gp-beta) | 16:11–16:13 | empty | All 5 stages passed |
| R2 (ex-gamma, gp-delta) | 16:16:13+ | 3 servers | gp-delta crashed on first permission-prompted Bash |
| R2 retry | 16:18+ | 3 servers | gp-delta crashed on first permission-prompted Write |
| Stage C | later | re-populated (had "disabled" via /mcp but it re-populated) | crashed identically |

Timeline from inbox JSON (R2):

16:16:50  ex-gamma → gp-delta   [DM] work request
16:16:54  gp-delta → team-lead  [permission_request] for Bash
16:17:03  team-lead → gp-delta  [permission_response] granted
~16:17    CRASH (renderer throws). gp-delta sends nothing further.
16:18:38  team-lead → gp-delta  [ping]              — written, read:false
16:21:40  team-lead → gp-delta  [shutdown_request]  — written, read:false

Process state during the wedge:

$ pgrep -lf "agent-id gp-delta"
40165  /Users/sauravvarma/.local/share/claude/versions/2.1.119
       --agent-id gp-delta@team-stress-test --agent-name gp-delta ...
$ tmux -L claude-swarm-18922 list-panes -a -F '#{pane_id} pid=#{pane_pid} dead=#{pane_dead}'
%2 pid=39574 dead=0   (gp-delta — wedged, but pane reports alive)

team-config.json continued to list gp-delta as isActive: true indefinitely.

Recovery on 2.1.119 (verified)

| Method | Result |
|---|---|
| SendMessage shutdown_request to wedged teammate | ❌ written to inbox, never marked read |
| SendMessage plain ping | ❌ same |
| Keyboard input on pane | ❌ no input box rendered |
| tmux kill-pane -t %N | ✅ kills pane + claude process |
| TeamDelete after kill-pane | ❌ fails: Cannot cleanup team with 1 active member(s). Workaround: manually remove the wedged member from ~/.claude/teams/<team>/config.json then TeamDelete succeeds. |

Suggested investigation areas

  1. Identify and confirm the change between 2.1.119 and 2.1.138 that resolved this — likely a fix in the component rendering the "N MCP server needs auth · /mcp" footer banner (composed <Box> inside <Text> only when paired with a permission-prompt panel).
  2. Independent of this specific crash, the agent-teams supervisor still has no path from "teammate Ink renderer dies" → "team lead sees agent_crashed event." Even if this exact composition is gone, the next render error in a teammate will present identically (silent wedge, isActive: true forever). Either catch render errors in the teammate process and emit an outbound agent_crashed SendMessage, or have the supervisor detect inbox writes accumulating with no read:true updates.
  3. TeamDelete should accept a force flag, or auto-clean when a member is unreachable.
  4. Related: mcp-needs-auth-cache.json repopulating within minutes even after /mcp disable (and disabledMcpServers not taking effect mid-session) — overlap with #48670.

Workaround for users still on 2.1.119 or earlier

Before any agent-teams session, ensure ~/.claude/mcp-needs-auth-cache.json is empty. If non-empty:

  • Complete /mcp auth for each listed server and then restart Claude Code (the disable does not take effect inside a running session), or
  • Add the listed server names to projects[<your-cwd>].disabledMcpServers in ~/.claude.json and restart.

Do not just delete the cache file — it re-populates within minutes.

Cross-references

  • #10313 (closed) — earlier generic Ink CLI crash
  • #38941 (closed) — Yoga/Ink renderer source dump on crash
  • #48670 (open) — MCP needs-auth-cache blocks reconnection even after re-auth (same underlying cache-staleness that produces the persistent banner observed here)

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗