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)

Open
#95,133 0 comments 0 reactions 1 assignee Claimed by @bogini View on GitHub
area:agent-view area:tui bug has repro platform: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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.