2.1.236 pins the terminal-title busy glyph to ✳ under ALL multiplexers, not just iTerm's tmux -CC

Status Open
Reported on v2.1.236
Maintainer reply None cached
Activity 1 comment · opened Aug 21, 2026

Summary

Since 2.1.236 the terminal-title busy indicator no longer animates inside plain
tmux: it is pinned to the idle glyph , and the / frames are
unreachable. The changelog entry describes this as a fix for iTerm's tmux
integration
(tmux -CC), but the code applies to every multiplexer — plain
tmux, screen and zellij included.

2.1.236: Fixed terminal tab titles jumping in tmux (iTerm tmux integration): the title is now written only when its text changes instead of animating every 960ms

Steps to reproduce

  1. Run claude inside a plain tmux session (not tmux -CC), with the terminal set to show the tab/window title.
  2. Send a prompt.
  3. Watch the tab title.

Expected: ◐ <topic> alternating with ◑ <topic> while Claude works.
Actual: ✳ <topic>, static, for the whole turn — indistinguishable from idle.

The idle-vs-busy signal is the useful part of the title for anyone running
several sessions across tmux windows, so this is a functional loss, not only a
cosmetic one.

Version bisect

Every @anthropic-ai/claude-code-linux-x64 tarball was unpacked and the binary
grepped for the gate name:

| version | tengu_static_title_under_mux | title under plain tmux |
|---|---|---|
| 2.1.232 – 2.1.235 | absent | / animates |
| 2.1.236 | present, default true | static ← first bad |
| 2.1.237 | present, default true | static |
| 2.1.238 | present, default true | static |

Cause

In 2.1.238 the title component reduces to:

uvs = ["◐", "◑"];   // busy frames
dvs = "✳";               // idle glyph
interval = 960;

staticUnderMux = getMux() !== null && gate("tengu_static_title_under_mux", true);
useInterval(tick, disabled || noPrefix || staticUnderMux || !isAnimating || !focused ? null : 960);
prefix = (isAnimating && !staticUnderMux) ? uvs[idx] ?? dvs : dvs;
useTerminalTitle(disabled ? null : noPrefix ? title : `${prefix} ${title}`);

and getMux() is:

function getMux() {
  const caps = attacherCaps();
  if (caps) return caps.mux;
  if (env.TMUX)   return "tmux";
  if (env.STY)    return "screen";
  if (env.ZELLIJ) return "zellij";
  return null;
}

So any TMUX/STY/ZELLIJ in the environment makes staticUnderMux true and
the busy frames dead code. The equivalent component in 2.1.235 has no mux term at
all.

No way to opt out locally

  • The gate defaults to true and both override paths are inert in the shipped

build: getEnvironmentOverrides() returns before it ever parses
CLAUDE_INTERNAL_FC_OVERRIDES, and readConfigOverrides() is return;.

  • CLAUDE_CODE_DISABLE_TERMINAL_TITLE is all-or-nothing — it removes the title

rather than restoring the animation.

  • The only workaround is unsetting TMUX for the process, which also disables

Claude Code's own tmux integration (isInsideTmuxSync, getUserTmuxSocket,
leader-pane lookup all read the same variable) and is inherited by every
command the Bash tool runs. I have pinned back to 2.1.235 instead.

Suggested fix

Scope the gate to the case it was written for — iTerm's tmux -CC control-mode
integration — rather than any multiplexer, or expose a setting
(terminalTitleAnimation) so the trade-off can be made per terminal. The two
glyphs are already the same display width, which was the 2.1.228 fix for the
tab-bar jitter in #17887, so plain tmux does not need the extra suppression.

Environment

  • Claude Code 2.1.238 (regression bisected to 2.1.236)
  • Linux 6.17.0-1032-oem, x64
  • tmux, TERM=tmux-256color, TERM_PROGRAM=tmux

View original on GitHub ↗

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