NO_COLOR=1 injected into tool subprocesses silently propagates to daemons and their child claude sessions — UI renders monochrome with no diagnostic hint
Environment
- Claude Code v2.1.220 (npm global install), Windows 11 Pro, Windows Terminal + pwsh 7.6.4
- Model: claude-fable-5
Summary
Claude Code injects NO_COLOR=1 (and GIT_TERMINAL_PROMPT=0, AI_AGENT=...) into the environment of Bash/PowerShell tool subprocesses. That is reasonable for keeping tool output clean, but the variable is inherited by anything those subprocesses launch. If a user restarts a long-lived daemon from inside a Claude Code session (a very common workflow: "rebuild and restart my service"), the daemon silently carries NO_COLOR=1 forever. Any claude session that daemon later spawns (e.g. via claude --remote-control) honors NO_COLOR and renders the entire UI monochrome — banner, status line, permission-mode indicator, custom statusLine ANSI output all gray. Diff colors still render, which makes the symptom look like a theme bug.
Repro
- Inside a Claude Code session, use the Bash/PowerShell tool to start any long-lived process (a service, a task-scheduler-launched watchdog target, etc.). It inherits
NO_COLOR=1. - Have that process launch
claude(directly or viawt/pwsh). - The new claude UI is fully monochrome. Nothing in the UI,
/theme, or/doctorindicates why.
Why this is painful to debug
/themepreviews look normal-ish and switching themes does nothing.- Edit-tool diffs still show green/red, so it does not look like a terminal capability problem.
- The polluted variable lives only in a daemon''s process environment — not in any shell profile, persistent env, or terminal profile — so every obvious place a user checks is clean. I only found it by reading the daemon''s environment block from its PEB.
Suggestions (any one would have saved hours)
/doctor(or the startup banner) should state "colors disabled: NO_COLOR is set in the environment" when color output is suppressed by env./themecould show the same warning instead of silently letting theme selection appear to have no effect.- Consider scoping the injection: set
NO_COLORonly for the immediate tool command (e.g. wrap the invocation) rather than leaving it in the inherited environment, or document the injected variable set explicitly so daemon-restart workflows can scrub them (related docs issue: #59585).
Workaround
Our orchestrator now scrubs NO_COLOR / GIT_TERMINAL_PROMPT / AI_AGENT / CLAUDECODE / CLAUDE_CODE_* / CLAUDE_PID from the env it passes to hosted claude sessions.