Agent team: command sent to new pane before shell is ready (race condition)

Resolved 💬 4 comments Opened Mar 21, 2026 by peterloron Closed Apr 21, 2026

Description

When spawning agent teammates, new terminal panes (iTerm2/tmux) are created correctly, but the command to start each Claude instance is sent before the shell has fully initialized. The command text is visible in the pane but never executes — the shell prompt just sits there. Manually copying and re-entering the command works fine.

Steps to Reproduce

  1. Use Claude Code with agent teams enabled (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1)
  2. Spawn multiple teammates via the Agent tool with team_name
  3. Observe that new panes open but the Claude command is pasted before the shell prompt is ready
  4. The command text is visible but not executed

Expected Behavior

The command should execute automatically in each new pane, starting the agent process.

Actual Behavior

The command text appears in the pane but the shell ignores it because it hasn't finished initializing. The pane sits idle until the user manually re-enters the command.

Root Cause Analysis

There's a race condition between pane creation and command execution. The command is sent to the new pane before the shell (zsh in my case) has finished loading its profile (.zshrc, zprezto modules, completions, etc.).

Shell startup profiling shows ~1 second of initialization time, primarily from:

  • zprezto module loading (pmodload): ~66ms
  • Completion system (compaudit + compinit): ~70ms
  • Various eval statements (starship, atuin, zoxide): ~130ms combined
  • Remaining time in file I/O and module discovery not captured by zprof

The gap between profiled time (~180ms) and actual startup (~1.03s) suggests significant time in operations zprof doesn't instrument.

Suggested Fix

Rather than adding a fixed delay (fragile, varies by machine), consider:

  1. Poll for shell readiness — send a sentinel command (e.g., echo __READY__) and wait for the expected output before sending the real command
  2. Use tmux send-keys with wait-for — tmux has a wait-for mechanism that can synchronize on channel signals
  3. Write command to a file, source it from shell profile — e.g., append source /tmp/claude-agent-cmd-$$ to a hook that runs after shell init

Environment

  • macOS (Darwin 25.4.0)
  • iTerm2
  • zsh with zprezto
  • Claude Code version: current (as of 2026-03-21)
  • tmux backend for pane management

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗