[BUG] Logo and "Thinking" animation colors are dull/washed-out inside tmux
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 running Claude Code inside tmux, the logo and "Thinking" animation text appear dull/washed-out compared to running Claude Code directly in the terminal. All other colors in tmux work correctly, and Claude Code's own text output (syntax highlighting, markdown, etc.) appears fine - only the branding UI elements (logo, thinking animation) are affected.
What Should Happen?
Logo and "Thinking" animation should have the same vibrant colors inside tmux as when running directly in the terminal.
Error Messages/Logs
Steps to Reproduce
- Open iTerm2
- Run claude - observe vibrant logo colors
- Open tmux inside iTerm2
- Run claude - observe dull/muted logo and "Thinking" animation colors
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.77 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Environment
- Claude Code version: 2.1.77
- OS: macOS (Darwin 25.3.0, Apple Silicon)
- Terminal: iTerm2
- tmux version: 3.6
- Shell: zsh
- Theme: dark
tmux config (relevant parts):
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:Tc"
set -g mouse on
set -s extended-keys on
set -as terminal-features ',xterm-256color:extkeys'
What I've tried (none of these fixed the issue):
- Setting COLORTERM=truecolor via set-environment -g COLORTERM truecolor
- Setting FORCE_COLOR=3 environment variable
- Adding set -ag terminal-overrides ",tmux-256color:RGB"
- Setting set -g allow-passthrough all
- Setting set-environment -g TERM_PROGRAM iTerm.app
- Setting COLORFGBG="15;0" in shell
- Changing default-terminal to xterm-256color
- Setting theme to dark via /theme
Truecolor verification:
Truecolor works correctly inside tmux for all other applications. Running the following produces three distinct, vibrant orange blocks:
printf '\e[38;2;231;111;44m██████ truecolor\e[0m\n'
printf '\e[38;5;208m██████ 256-color\e[0m\n'
printf '\e[38;2;204;102;0m██████ truecolor darker\e[0m\n'
Suspected cause
Claude Code likely performs its own terminal capability detection for UI elements and falls back to a muted color palette when it detects tmux, regardless of actual truecolor support.
Showing cached comments. Read the full discussion on GitHub ↗
9 Comments
<img width="106" height="97" alt="Image" src="https://github.com/user-attachments/assets/b1658c32-31d9-441a-aac5-816ad4d8822e" /> - Claude logo in iTerm2
<img width="105" height="88" alt="Image" src="https://github.com/user-attachments/assets/fc7c6cfe-2dab-4233-87c5-37dd184d80ff" /> - Claude logo in tmux
accidentally closed issue, the problem still persists
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
I can confirm the same is true on ghostty within tmux, and that this is a regression in 2.1.77, 2.1.76 renders colors correctly.
<img width="2014" height="664" alt="Image" src="https://github.com/user-attachments/assets/4b10fda5-fe86-4788-b64c-5a606070b33a" />
Confirming this regression in v2.1.77. Tested across multiple terminals and narrowed down the root cause.
Environment
Key finding:
$TMUXenv var triggers the desaturationRunning Claude Code with the
TMUXvariable unset restores correct colors inside tmux:The screenshot below shows Claude Code launched with
env -u TMUX claudeinside tmux — colors arecorrect, matching non-tmux rendering.
This confirms Claude Code v2.1.77 checks
$TMUXand applies a different (muted) color palette,regardless of actual terminal color capabilities.
What didn't help
FORCE_COLOR=3 claude— no effectTERM_PROGRAM=ghostty claude— no effectCOLORTERM=truecoloris set and verifiedterminal-overrides/terminal-featureschanges in tmux configAdditional data points
issue
working
<img width="1182" height="777" alt="Image" src="https://github.com/user-attachments/assets/80d41376-f1cf-4ba4-b38e-21d60aa954ba" />
Found the exact root cause in the bundled
cli.js:This explicitly downgrades chalk's color level to 2 (256-color) whenever
$TMUXis set, regardless of actual terminal capabilities.Additional context from psmux (tmux-compatible multiplexer on Windows)
I'm running Claude Code inside psmux, a tmux-compatible terminal multiplexer for PowerShell on Windows. It creates ConPTY with
PSEUDOCONSOLE_PASSTHROUGH_MODEand setsCOLORTERM=truecolorfor child processes. Full 24-bit RGB works correctly for all other applications.Root cause identified: In the bundled
cli.js, theIB3()function unconditionally caps chalk's color level to 2 (256-color) when theTMUXenv var is set:This runs after
FORCE_COLORdetection, so evenFORCE_COLOR=3cannot override it. The result is that RGB theme colors get approximated to the nearest 256-color palette entry, which is why some colors look fine (close match exists) while others appear washed out/desaturated.Suggested fix: Rather than blanket-capping at level 2, check the multiplexer's actual capability — e.g.,
tmux display -p '#{client_termfeatures}'reportsRGBon capable setups, or respectCOLORTERM=truecoloreven whenTMUXis set.Environment: Windows 11, psmux 3.2.0,
TERM=xterm-256color,COLORTERM=truecolor, Claude Code 2.1.78.There's an env var that fixes this.
Add to your shell rc, open a new pane, done.
It's documented at https://code.claude.com/docs/en/env-vars
---
Why it works
The check in the bundled JS already has an opt-out:
Setting the env var returns early before chalk gets capped at level 2, so RGB sequences leave the process unmangled.
---
Version timeline (verified by inspecting old npm tarballs)
| Version | Date | State |
|---|---|---|
| 2.1.76 | 2026-03-14 | No clamp — colors fine |
| 2.1.77 | 2026-03-16 | Clamp added — regression starts |
| 2.1.78–2.1.81 | through 2026-03-20 | Clamp present, no escape hatch |
| 2.1.83 | 2026-03-24 |
CLAUDE_CODE_TMUX_TRUECOLORadded || docs | 2026-04-15 | Env var finally documented |
This bug persists / has freshly manifested specifically in the VS Code integrated terminal.
CLAUDE_CODE_TMUX_TRUECOLORoverride set (fixes tmux, does not fix VS Code).Environment (VS Code terminal, outside of tmux)
Claude Code:
2.1.160Comparison
Left: Enter
tmuxthenclaude(works ✅). Right:claudeonly (washed out ❌).<img width="956" height="280" alt="Image" src="https://github.com/user-attachments/assets/0e7c3ba2-2eb2-469f-99de-712b14359004" />
[New] Claude investigation (pasted) ⬇️
I was able to resolve this with a
TERM_PROGRAM=genericoverride for my VS Code (https://github.com/huntie/dotfiles/commit/ef43f42402b4276b0948974aacce303032316cb2).<details>
<summary><strong>Investigation</strong></summary>
Investigation: dull/washed-out logo + spinner under VS Code's integrated terminal
TL;DR: Not a colour-depth problem. Claude Code detects truecolor correctly and emits 24-bit RGB. The desaturation is triggered by Claude's own
vscode/xterm.js render branch — gated onTERM_PROGRAM === "vscode". Removing that one signal (terminal capabilities otherwise unchanged) restores vibrant colours. Same family as #35148, but a different code path from the tmux case.Environment
@anthropic-ai/claude-code-*@2.1.181; the JS is identical across platform builds).Symptom
Brand orange and the "Thinking" spinner gradient render muted/desaturated. Everything else — syntax highlighting, markdown, ANSI output — is correct. Only the RGB-coloured branding is affected.
What this is NOT (ruled out empirically)
| Hypothesis | Check | Result |
|---|---|---|
| 256-colour quantisation (
chalk.level === 2, the salmon-cube bug) | diagnostic printslevel: 3,COLORTERM: 'truecolor'| Ruled out — at truecolor ||
boostChalkLevelForXtermJs(256→3) needed but not firing | already level 3 pre-boost | Ruled out — boost irrelevant || VS Code
terminal.integrated.minimumContrastRatioluminance adjustment | already set to1; other apps render full-saturation RGB in the same terminal | Ruled out || tmux passthrough clamp |
inTmux: false| Ruled out || Terminal can't do truecolor | truecolor swatch renders vibrant in the same VS Code terminal | Ruled out — emulator is fine |
Diagnostic output from the affected terminal:
Confirmed trigger
The deciding A/B. With the terminal's colour capabilities held constant (still
COLORTERM=truecolor, still xterm.js), only theTERM_PROGRAMsignal changes:So the differentiator is
TERM_PROGRAM === "vscode", not anything about reported colour support.In the bundle this maps to the "am I in xterm.js?" predicate, which several render paths key off:
When
D_()is true, Claude takes an xterm.js-specific rendering branch that the Ghostty and tmux paths never touch. UnsettingTERM_PROGRAMmakesD_()false (the XTVERSION probe does not independently returnxterm.json this setup), and the branding renders at full saturation.Candidate mechanism (not yet confirmed)
D_()gates more than colour level — in the bundle it also controls glyph-atlas behaviour in the renderer:maybeProactiveAtlasReset,proactiveAtlasResetOnFocus,forceRedrawall emit an atlas/palette reset (OSC 104;255) only whenD_(), and there is glyph-cardinality telemetry (tengu_render_glyph_cardinalitywithstylepool_overflowed/atlas_keys_saturated,is_xtermjs). Leading candidates, in rough order:D_()branch.This can be discriminated by capturing and diffing the raw output streams (not yet run):
A differing SGR inventory points to (1)/(3); orange consistently wrapped with
2;points to (2).Workaround
Mask the trigger for the VS Code terminal only:
Tradeoff: this also hides
TERM_PROGRAMfrom Claude's VS Code extension integration (in-editor diff, selection/diagnostic context), since that keys offTERM_PROGRAM === "vscode"too. A per-command Fish wrapper guarded onvscodenarrows the blast radius to theclaudeprocess if IDE integration matters.Suggested direction
The terminal advertises and supports truecolor, and Claude emits the correct RGB bytes — proven by the fact that suppressing the
D_()branch alone restores them. The xterm.js render branch is muting colours the renderer can display. Worth checking the atlas/stylepool path (candidate 1) and the faint-render assumption (candidate 2) against the stream capture above.</details>