TmuxBackend: cached window target (wN1) never invalidates, breaks teammate spawning after window topology changes

Resolved 💬 2 comments Opened Mar 3, 2026 by ArthurAllshire Closed Apr 1, 2026

Bug Description

The TmuxBackend caches the tmux window target string (wN1) at module scope (cli.js:2678) on first successful call to getCurrentWindowTarget(). This cache is never reset or invalidated. When tmux windows are killed and recreated during a long-running session, the cached target becomes stale, causing all subsequent createTeammatePaneWithLeader() calls to fail with:

Could not determine pane count for current window

Reproduction Steps

  1. Start a Claude Code session in tmux
  2. Successfully spawn teammates using Task with team_name parameter (works fine initially)
  3. Kill some tmux windows (e.g., tmux kill-window -t :1)
  4. Create new tmux windows
  5. Try to spawn teammates again with Task + team_name
  6. ERROR: "Could not determine pane count for current window"

Root Cause

In cli.js:2678:

  • wN1 is declared at module scope and set once by getCurrentWindowTarget()
  • getCurrentWindowPaneCount(windowTarget) runs tmux list-panes -t <wN1>
  • After window topology changes, wN1 points to a window/session target that no longer exists
  • tmux list-panes exits non-zero, the function returns null, and the error is thrown
  • The error is reported to Sentry only (via H6()), not to debug logs, making it hard to diagnose

Key Evidence

  • Fresh sessions always work: New Claude processes compute wN1 fresh from current tmux state
  • Long-running sessions break: After multiple window create/kill cycles, the cache becomes stale
  • Workaround: Restart the Claude session to force fresh wN1 computation

Suggested Fix

One of:

  1. Invalidate on failure: If getCurrentWindowPaneCount() returns null, reset wN1 = null so the next call recomputes
  2. TTL cache: Expire wN1 after N seconds
  3. Per-instance cache: Don't cache at module scope; compute per TmuxBackend instance
  4. Recompute on error: In createTeammatePaneWithLeader(), if pane count is null, try recomputing window target once before throwing

Option 1 is the simplest and most robust fix.

Environment

  • Claude Code version: 2.1.62
  • tmux version: 3.4
  • Platform: Linux (Ubuntu, running on Sky/AWS)
  • Relevant file: /usr/lib/node_modules/@anthropic-ai/claude-code/cli.js lines 2671-2678

View original on GitHub ↗

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