teammateMode "tmux" silently falls back to in-process since ~v2.1.50+

Status Fixed / completed
Reported on v2.1.62
Maintainer reply None cached
Activity 11 comments · opened Feb 27, 2026 · closed Mar 14, 2026

Environment

  • Claude Code version: 2.1.62
  • OS: macOS Darwin 25.4.0
  • tmux: 3.6a
  • $TMUX: set (/private/tmp/tmux-501/default,30374,3)
  • Config: "teammateMode": "tmux" in ~/.claude/settings.json
  • CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: 1

Bug Description

All teammates spawn with backendType: "in-process" and no tmux panes are created, despite "teammateMode": "tmux" being explicitly set in settings. This worked correctly on earlier versions (~Feb 8-9, 2026) but broke silently around Feb 19.

Expected Behavior

With "teammateMode": "tmux", agents should spawn in tmux split-panes (or new windows), producing real pane IDs like %1, %8, %25, etc.

Actual Behavior

All agents spawn in-process. Team config files show "tmuxPaneId": "in-process" and "backendType": "in-process" for every teammate. No tmux panes are created.

Evidence

Working teams (Feb 8-9, earlier Claude Code version):

| Team | Pane IDs | Backend |
|------|----------|---------|
| tidy-conjuring-axolotl | %1, %2, %3 | tmux |
| fluffy-wishing-duckling | %6, %7 | tmux |
| game-polish | %8 | tmux |
| word-survivor-audit | %9, %16 | tmux |
| word-survivor-v2 | %25 | tmux |
| v2-playable | %39 | tmux |

Broken teams (Feb 19+, Claude Code ~2.1.50+):

| Team | Pane IDs | Backend |
|------|----------|---------|
| sim-fix | all in-process | in-process |
| animation-prototypes | all in-process | in-process |
| delightful-v2 | all in-process | in-process |
| polymarket-refactor | all in-process | in-process |
| great | all in-process | in-process |
| life-audit | all in-process | in-process |
| motion-system | all in-process | in-process |

Root Cause Analysis

From the compiled binary, the teammate spawn decision flows through a gatekeeper function (deobfuscated as cv() / isInProcessEnabled):

// Decision function — called before any spawn
function cv() {
  // CHECK 1: Non-interactive session (process.stdin.isTTY)
  if (F_())            // ← If stdin is not a TTY, returns true immediately
    return true;       // → FORCE IN-PROCESS, skip config check

  // CHECK 2: Read teammateMode from config
  let T = U28();       // reads captured teammate mode
  if (T === "in-process") return true;
  else if (T === "tmux") return false;
  else /* "auto" */ return !WwR();
}

The spawn entry point:

async function k28(T, R) {
  if (cv())            // ← If true, config is never consulted
    return b28(T, R);  // → in-process spawn (hardcoded)

  if (T.use_splitpane !== false)
    return P28(T, R);  // → tmux split-pane spawn
  return y28(T, R);    // → tmux new-window spawn
}

The problem: The non-interactive TTY check (F_(), which checks process.stdin.isTTY) runs before the config check. If process.stdin.isTTY returns false (even inside a real terminal session), it short-circuits to in-process mode and the "teammateMode": "tmux" setting is never consulted.

The binary contains the log message "[BackendRegistry] isInProcessEnabled: true (non-interactive session)" on this code path, confirming this is the bypass route.

Suggested Fix

  1. When teammateMode is explicitly "tmux", the non-interactive TTY check should not override it. The user has explicitly opted in to tmux mode — that should be respected regardless of TTY state.
  2. If a fallback from tmux to in-process does occur, emit a visible warning/log rather than silently degrading. Something like: "[BackendRegistry] Warning: teammateMode is 'tmux' but falling back to in-process because stdin is not a TTY"

Reproduction

  1. Be inside a tmux session with $TMUX set
  2. Set "teammateMode": "tmux" in ~/.claude/settings.json
  3. Set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
  4. Create a team and spawn teammates
  5. Check ~/.claude/teams/<team-name>/config.json — all members have backendType: "in-process" instead of "tmux"

View original on GitHub ↗

11 Comments

github-actions[bot] · 6 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/26244

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

kylesnav · 6 months ago

Same problem, different reasons.

kylesnav · 6 months ago

Related: #26244

Same root cause — isInProcessEnabled() checks isTTY/isInteractive before consulting teammateMode, so an explicit "tmux" setting gets silently overridden. Both issues propose the same fix (check teammateMode === "tmux" first).

The difference is why isTTY is falsy: here it's a macOS regression introduced around v2.1.50, while #26244 hits it on Windows where Bun SFE's process.stdout.isTTY is always undefined. A fix for the shared code path should resolve both.

MrAshRhodes · 5 months ago

the same behaviour happens when using the flag --teammate-mode tmux as well

danielpiva · 5 months ago

Also happening here, it's a black box, can't see what they're doing.

I'm on macOS Sequoia using Ghostty.

kylesnav · 5 months ago

@danielpiva the agent view requires the iTerm2 plugin for tmux, so it's not a feature available for Ghostty in general :( devastating I know.

kylesnav · 5 months ago

this is resolved

<img width="1109" height="919" alt="Image" src="https://github.com/user-attachments/assets/e4d1e7d8-caaa-476d-8e77-c3d397778d49" />

MrAshRhodes · 5 months ago

@kylesnav
it doesnt work on ghostty? previously it did...

version - 2.1.63

<img width="2028" height="835" alt="Image" src="https://github.com/user-attachments/assets/e7a5c479-821b-485c-9303-e0702d70023c" />

danielpiva · 5 months ago

It pretty much worked ~fine with Ghostty until not so long ago :(

It's sad, really. Not to mention that the flickering is back for me.

danielpiva · 5 months ago
It pretty much worked ~fine with Ghostty until not so long ago :( It's sad, really. Not to mention that the flickering is back for me.

@MrAshRhodes I thought I was being insane, but yes it pretty much worked fine with Ghostty + tmux just a few days ago on 2.1.69!

<img width="3680" height="2384" alt="Image" src="https://github.com/user-attachments/assets/2caca902-c015-46f5-bb98-69c6c91aa75b" />

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.