anthropics / anthropics/claude-code
[Bug] Daemon spawns workers with a hardcoded 120x30 PTY when the client size is not yet known, then never resizes them (Windows)
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Environment
- Claude Code `2.1.274` (BUILD_TIME `2026-09-16T21:39:42Z`, GIT_SHA `1efcc1361e649ab98800b43a7df307043397a9ba`)
- Windows 11 Pro `10.0.26200`, Windows Terminal, ConPTY
- Backend: daemon (`claude daemon run --origin transient`), workers spawned by the supervisor
## Summary
Workers that the daemon spawns before it knows the client's terminal size are created
with a hardcoded **120x30** PTY. Nothing corrects that size afterwards, so the TUI
paints a 120x30 image into the real (larger) window: content occupies only the
top-left, the rest of the window stays blank.
## Symptoms
- Open a terminal window that is larger than 120x30 (e.g. 210x59), start `claude`,
and enter a session within the first seconds after the daemon starts.
- The session renders at 120x30 inside the 210x59 window — the input box separator
stops at ~57% width, the footer sits at ~51% height, bottom and right are black.
- **Restarting the session does not help** — every newly spawned worker is born at
120x30 again.
- **Maximizing the window (or any real window-size change) fixes it.**
- **Closing the terminal and reopening it fixes it**, even without resizing.
## Evidence
`~/.claude/daemon/roster.json` records the size that each worker is created with,
and `dispatch.createdAt` records when that decision was made. Three workers from the
same supervisor process (`2.1.274`), same machine, same session:
| worker | `dispatch.createdAt` | `dispatch.cols` x `rows` | daemon knew the client size? |
|---|---|---|---|
| `bad901d6` (spare) | 20:06:38.874 | 120 x 30 | no — daemon had not finished starting |
| `138b5e43` (fleet) | 20:06:46.091 | 120 x 30 | no — attach gesture started 9 ms earlier |
| `ec131221` (fleet) | 20:22:25.009 | **210 x 59** | yes — daemon had been up 16 minutes |
The size is passed straight through to the pseudo-console host, whose command line
carries it literally:
```
--bg-pty-host \\.\pipe\cc-daemon--pty-bad901d6 120 30 -- claude.exe --session-id bad901d6-...
--bg-pty-host \\.\pipe\cc-daemon--pty-138b5e43 120 30 -- claude.exe --resume ...
--bg-pty-host \\.\pipe\cc-daemon--pty-ec131221 210 59 -- claude.exe --resume ...
```
Geometry check against a screenshot of the broken window: the window is 210 columns
wide, the rendered content stops at 54.3% of its width (120 / 210 = 57.1%), and the
footer row sits at 48% of its height (30 / 59 = 50.8%). That is consistent with a
120x30 buffer being painted into a 210x59 window.
## Analysis
Two things combine:
1. **The size is fixed at dispatch creation and never revisited.** If the daemon does
not yet have the client's real size at that moment, it uses a 120x30 fallback, and
that value is baked into the worker's PTY for its whole lifetime.
2. **Nothing re-sends the size after the attach completes.** The client only emits a
`resize` op when *its own* size *changes*. Immediately after attaching, its size has
not changed, so no `resize` op is sent and the worker is never told the real size.
There is also no SIGWINCH fallback on Windows — `signalPtyPgrp()` returns early when
the platform is `win32`.
This is why a window resize fixes the problem but a restart does not: the resize
produces a genuine size change, which is the only thing that triggers the correction.
I am reasonably confident about (1) because the timestamps above line up with the
daemon's startup window. I have not pinned down exactly where the daemon learns the
client size, or why it does not have it by the time the first `attach` arrives — that
part is inference from the data above, not from reading the code.
## Steps to reproduce (tentative)
1. Close all Claude Code windows so the transient daemon exits.
2. Open a terminal window larger than 120x30.
3. Start `claude` and enter a session immediately, before the daemon has been up long.
4. Observe the session laid out at 120x30 with the bottom/right of the window blank.
5. Wait a minute, then create or enter another session — that one comes out at the
correct size.
Step 5 is the part I am least sure reproduces consistently; steps 1-4 reproduce every
time on this machine.
## Expected behavior
A worker's PTY should be created at the client's current terminal size, or resized as
soon as the client reports its size during attach — so the first entry is laid out
correctly and no workaround is needed.
## Workaround
Change the terminal size once (maximize, or maximize and restore). That produces a real
size change, which resizes the PTY and reflows the TUI.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.