[BUG] Agent team spawning fails silently — launch commands split at ~255 bytes, agents never start
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When using experimental agent teams (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1), Claude Code spawns teammate agents into tmux panes via tmux send-keys. The agent launch command is ~400–500 characters:
cd /path/to/project && env CLAUDECODE=1 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
/path/to/claude --agent-id <name>\@<team> --agent-name <name> --team-name <team>
--agent-color <color> --parent-session-id <uuid> --agent-type <type>
--settings /tmp/claude-settings-<hash>.json --model <model>
This command gets split at ~255 bytes into two fragments. Bash executes the first fragment (incomplete — fails silently), then executes the second fragment as a standalone command:
bash: ent-alpha: command not found
The agent never starts. The parent session reports "Spawned successfully" but the teammate is dead.
What Should Happen?
The full agent launch command should execute as a single shell command in the tmux pane, successfully starting the teammate agent process.
Error Messages/Logs
Observed across 5 agent spawn attempts — the split point is always at byte 255–256:
# Pane capture showing the split:
$ tmux capture-pane -t claude-swarm:0.1 -p -S -10
cd /path/to/project && env CLAUDECODE=1 ... --agent-name my-research-agent --team-name my-team
user@host: /path/to/project $ earch-agent --team-name my-team --agent-color yellow ...
bash: earch-agent: command not found
user@host: /path/to/project $
The fragment `earch-agent` is the tail of `my-research-agent` — the command was split mid-word at ~255 bytes from the start of the transmitted text.
Note: manually running `tmux send-keys` with the same command from a shell does NOT reproduce the split, even in 40-column panes. The issue is specific to how Claude Code delivers commands to tmux.
Steps to Reproduce
- Enable agent teams:
``json``
// ~/.claude/settings.json
{ "env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" } }
- Start Claude Code and create a team with an agent whose combined launch command exceeds ~255 bytes. This happens naturally when any of these are long:
- The working directory path (
cd /long/path/to/project && ...) - The agent name (
--agent-name my-descriptive-agent-name) - The parent session UUID (
--parent-session-id <36-char-uuid>)
- Observe the tmux pane for the spawned agent:
```bash
# Find the claude-swarm tmux socket
ls /tmp/tmux-$(id -u)/claude-swarm-*
# Capture the pane content
SOCK=/tmp/tmux-$(id -u)/claude-swarm-*
tmux -S $SOCK capture-pane -t claude-swarm:0.1 -p -S -10
```
- The pane shows the command split into two fragments with
command not foundfor the second fragment.
Note on manual reproduction: Running tmux send-keys manually from a shell does NOT reproduce the split — even with 400+ byte commands in 40-column panes. The split is only triggered by Claude Code's agent spawning path. This suggests the issue is in Claude Code's internal tmux integration, not in tmux or the kernel.
Root Cause Analysis
Disproved hypotheses
1. Pane width: Initially suspected narrow tmux panes caused visual line-wrapping that broke the command. Disproved — manually sending a 362-byte command via tmux send-keys to a 40-column pane executes correctly as a single command. Bash and the kernel PTY layer handle wrapped input properly in canonical mode.
2. MAX_CANON / PTY buffer limits: Hypothesized that the kernel's MAX_CANON constant (255, defined in include/uapi/linux/limits.h) imposed a hard limit on canonical input. Disproved — MAX_CANON is never referenced by the N_TTY line discipline driver (drivers/tty/n_tty.c). It is a POSIX compatibility constant only. The actual N_TTY buffer is N_TTY_BUF_SIZE (4096 bytes). Independent testing confirms commands of 400+ bytes pass through tmux send-keys → PTY → bash without splitting, regardless of pane width.
3. GNU Screen nesting: Tested whether running Claude Code inside a GNU Screen session (TERM=screen.xterm-256color) caused the split via Screen's terminal emulation layer. Disproved — the same split occurs when Claude Code runs directly in an xterm-256color terminal with no screen session.
Actual root cause: Claude Code's tmux command delivery
The split is specific to how Claude Code sends commands to tmux panes, not to any system-level limit. When the same commands are sent manually via tmux send-keys from a shell, they execute correctly even in 40-column panes.
The observed 255-byte split point is consistent across Claude Code spawns but does NOT reproduce with manual tmux send-keys. This indicates Claude Code's agent spawning code either:
- Breaks the command into chunks before sending (possibly at an internal buffer boundary of ~255 bytes)
- Uses a different tmux API that has its own chunking behavior
- Has a race condition where parts of the command are sent before the pane's shell is ready to receive input
Without access to Claude Code's source, the exact mechanism cannot be determined. The symptom — command splitting at a consistent byte offset — points to an internal buffering strategy in Claude Code's tmux integration layer.
Suggested Fix
The fix should happen inside Claude Code's agent spawning code. Instead of sending the full launch command via tmux send-keys, write it to a temporary script and send a short source command:
# Instead of:
tmux send-keys -t $PANE "$LONG_COMMAND" Enter # 400+ bytes → splits at ~255
# Do:
TMPF=$(mktemp /tmp/claude-agent-cmd-XXXXXX.sh)
printf '%s\n' "$LONG_COMMAND" > "$TMPF"
tmux send-keys -t $PANE "source $TMPF; rm -f $TMPF" Enter # ~50 bytes → no split
This keeps the transmitted command well under the ~255-byte threshold regardless of agent name length, working directory depth, or UUID size.
User-side workaround
Until fixed upstream, users can work around this with a tmux wrapper at ~/.claude/bin/tmux (requires ~/.claude/bin to be in PATH before /usr/bin):
#!/bin/bash
REAL_TMUX=/usr/bin/tmux
# Force wide new-session dimensions
if [[ " $* " == *" new-session "* || " $* " == *" new "* ]]; then
if [[ " $* " != *" -x "* ]]; then
exec "$REAL_TMUX" "$@" -x 2000 -y 50
fi
fi
# Intercept send-keys: if text payload exceeds 200 bytes, use temp script
if [[ "$1" == "send-keys" || "$2" == "send-keys" ]]; then
args=("$@")
text=""
for i in "${!args[@]}"; do
a="${args[$i]}"
[[ "$a" == "send-keys" || "$a" == "-S" || "$a" == "-t" ]] && continue
if (( i > 0 )); then
prev="${args[$((i-1))]}"
[[ "$prev" == "-S" || "$prev" == "-t" ]] && continue
fi
[[ "$a" == "Enter" || "$a" == "C-m" ]] && continue
if [[ -z "$text" ]]; then
text="$a"
text_idx=$i
fi
done
if [[ -n "$text" ]] && (( ${#text} > 200 )); then
tmpf=$(mktemp /tmp/claude-agent-cmd-XXXXXX.sh)
printf '%s\n' "$text" > "$tmpf"
args[$text_idx]="source $tmpf; rm -f $tmpf"
exec "$REAL_TMUX" "${args[@]}"
fi
fi
exec "$REAL_TMUX" "$@"
Users can also add Pre/PostToolUse hooks in ~/.claude/settings.json to resize existing agent tmux sessions, which helps subsequent agent spawns in the same session:
{
"matcher": "Agent",
"hooks": [
{
"type": "command",
"command": "for sock in /tmp/tmux-*/claude-swarm-*; do [ -S \"$sock\" ] && tmux -S \"$sock\" resize-window -x 2000 2>/dev/null; done; exit 0",
"timeout": 5
}
]
}
Manual recovery for a failed agent spawn
SOCK=/tmp/tmux-$(id -u)/claude-swarm-*
# Copy the failed command from the pane scrollback, write to a file:
cat > /tmp/claude-agent-cmd.sh << 'SCRIPT'
env CLAUDECODE=1 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 ... --model sonnet
SCRIPT
# Source it (40 bytes — well under the ~255-byte threshold):
tmux -S $SOCK send-keys -t claude-swarm:0.<pane> 'source /tmp/claude-agent-cmd.sh' Enter
Is this a regression?
Unknown. This may have existed since the initial implementation of CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS. Any project with a working directory path longer than ~200 characters, or any agent with a name longer than ~15 characters, will likely produce a launch command that exceeds the ~255-byte threshold where splitting occurs.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.84
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
iTerm2
Additional Information
- The split does NOT reproduce when running
tmux send-keysmanually from a shell — even with 400+ byte commands in 40-column panes. The issue is specific to Claude Code's tmux integration. - The split consistently occurs at ~255 bytes across all observed failures, suggesting an internal buffer size in Claude Code's command delivery path.
- The kernel's
MAX_CANON(255) andN_TTY_BUF_SIZE(4096) are NOT the cause — the N_TTY driver does not referenceMAX_CANON, andN_TTY_BUF_SIZEis large enough. Manual testing confirms no kernel-level splitting. - The issue is 100% reproducible — every Claude Code agent spawn with a launch command exceeding ~255 bytes fails.
- The parent session always reports "Spawned successfully" even when the agent fails to start, making the failure silent unless the user inspects the tmux pane.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗