[BUG] theme: "auto" never updates on Windows Terminal — resample is gated solely on DECSET 2031, which WT does not implement
Summary
"theme": "auto" never follows a live light/dark switch on Windows Terminal. It resolves once at startup and then stays wrong until Claude Code is restarted, so a user who switches appearance once in the morning and once at night has to run /theme twice a day.
The detection itself is fine. Only the trigger is missing: the resample is gated solely on DECSET 2031, which Windows Terminal does not implement — and has explicitly declined to implement.
Root cause
Claude Code enables CSI ? 2031 h, parses CSI ? 997 ; [12] n off stdin, and re-queries the background with OSC 11 when that report arrives. If the terminal never sends the report, the re-query never runs.
Windows Terminal rejected mode 2031 in microsoft/terminal#20335 (closed 2026-07-31, "somewhat under-specified"). The maintainer's guidance in that thread is directly relevant:
For now, applications should be able to figure out the prevailing _color scheme_ background with an xterm color resource query (11;?) and make lightness decisions based on that.
So on Windows Terminal — the default terminal on Windows 11, i.e. most Windows users — auto silently degrades to detect-once-at-startup.
Measurements
Windows 11, Windows Terminal 1.24.11911.0, Claude Code 2.1.261. Queried from a live console:
| Query | Reply |
|---|---|
| DECRQM ? 2031 (theme notify) | 0 — NOT RECOGNIZED |
| DECRQM ? 2026 (sync update, control) | supported |
| DECRQM ? 2004 (bracketed paste, control) | supported |
| OSC 11 before flip (light) | ESC]11;rgb:fafa/fafa/fafa |
| OSC 11 after flip (dark) | ESC]11;rgb:2828/2c2c/3434 |
The two controls answering "supported" confirm the 0 is a real unrecognized-mode reply, not a probe artifact. Note the OSC 11 rows: Windows Terminal reports the new background immediately after the theme flip. The information Claude Code needs is available the whole time; nothing ever asks for it again.
With ?2031 enabled and the OS theme flipped, nothing arrives on stdin — confirmed over a 45-second window across several flips.
Confirmation that only the trigger is missing
Injecting the report Windows Terminal never sends, straight into the session's console input buffer:
ESC [ ? 997 ; 2 n
Claude Code immediately re-queried OSC 11 and switched to the correct theme, in a running session, with no restart. Injecting ;1n switches it back. So the OSC 11 path, the parser, and the repaint all work — they are simply never invoked on this terminal.
Repro
- Windows 11 + Windows Terminal, with a profile whose
colorSchemeis a{ "dark": ..., "light": ... }pair so the terminal follows the OS theme. "theme": "auto"insettings.json.- Start Claude Code in light mode. Switch Windows to dark mode.
- Terminal repaints; Claude Code keeps rendering the light theme indefinitely. Only a restart (or
/theme) fixes it.
Request
When DECRQM ? 2031 reports the mode as unrecognized, fall back to re-querying OSC 11 rather than waiting for a notification that will never arrive — on focus regain, on an interval, or both. Per the Windows Terminal maintainer's comment above, this is the sanctioned approach on that terminal.
The binary already contains a focus-driven re-query path, but it appears gated behind CLAUDE_BG_BACKEND === "daemon" rather than behind 2031 support. Reusing it whenever 2031 is unavailable may be most of the fix.
Related: #63433 asked for this on macOS and was closed as not planned; 2031 support has since landed, which covers terminals that implement the mode but leaves Windows Terminal users in the detect-once state described here.
Environment
- Platform: win32 (Windows 11 Enterprise 26200)
- Terminal: Windows Terminal 1.24.11911.0
- Claude Code: 2.1.261
settings.json:"theme": "auto"
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗