[BUG] Background sessions never receive SIGWINCH — TUI never reflows on terminal resize

Status Open
Reported on v2.1.232
Maintainer reply None cached
Activity 1 comment · opened Aug 14, 2026

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?

Environment

  • Claude Code: 2.1.232 (native, linux-x64)
  • OS: CentOS Stream 9, kernel 6.16, x86_64
  • Terminal: Ghostty over SSH, inside tmux 3.7b
  • Config: "tui": "fullscreen" (also reproduces with "default")

Summary

Background sessions (claude --bg, or dispatched from claude agents / "agent view") are given a
pty that is not their controlling terminal. The kernel delivers SIGWINCH only to the
foreground process group of a pty's session, so a process with no controlling terminal can never
receive one.

The pty itself is resized correctly, and the renderer even has a working SIGWINCH handler
installed — it just never fires. The session keeps drawing at whatever size it had at startup,
forever.

Foreground sessions are unaffected.

Root cause

Every layer except signal delivery is correct, which is what makes this hard to spot:

| layer | state after a resize |
| --- | --- |
| terminal / ssh / tmux client / tmux pane | correct (479) |
| the session's pty — stty -F /dev/pts/N size | correct (479) |
| SigCgt bit 27 on the renderer | set — a SIGWINCH handler is installed |
| /proc/<pid>/stat field 7 (tty_nr) | 0 — no controlling terminal |
| ps -t /dev/pts/N | empty — nothing owns that pty as its ctty |
| the rendered frame | stale (239) — the handler never fires |

Concretely, for a background renderer:

$ readlink /proc/<PID>/fd/1
/dev/pts/26

$ awk '{print $7}' /proc/<PID>/stat        # tty_nr
0                                          # <-- no controlling terminal

$ awk '$1=="SigCgt:"{print $2}' /proc/<PID>/status
000000017b826cff                           # bit 27 set: SIGWINCH IS handled

$ ps -t /dev/pts/26                        # nothing claims it as ctty
(empty)

$ stty -F /dev/pts/26 size                 # pty geometry is correct
97 197

Proof

Delivering the signal by hand — which the kernel cannot do — fixes it instantly:

$ kill -WINCH <renderer-pid>
# frame immediately re-lays-out from 239 to 479 columns

Why the obvious workarounds don't help

  • Resizing again / waiting — no hook exists to fire; the pty is already the right size.
  • Ctrl-L, tmux zoom/unzoom — these do force a repaint, but it repaints at the cached size.
  • kill -WINCH on the foreground session — no effect; wrong process. The stale frame belongs to

the background renderer.

  • /tui default — cannot help. It reports:

> Saved. Background sessions always use the fullscreen renderer while attached; the default
> renderer will apply to sessions started directly with claude.

So the renderer-switch restart never applies to an attached background session.

  • Detach and reattach in agent view — works sometimes, because attaching re-pushes a size; it

is a race.

A foreground claude in the same terminal reflows correctly (verified 100 → 160 columns with
both tui: "default" and tui: "fullscreen"), which isolates this to the background-session pty
path.

Suggested fix

Either of:

  1. Have the pty host setsid() + ioctl(TIOCSCTTY) in the child so the pty becomes its controlling

terminal. The kernel then delivers SIGWINCH on every resize and no application-level plumbing
is needed. This seems like the correct fix.

  1. Have agent view send an explicit resize message over the background-session socket and have the

child apply it (TIOCSWINSZ on itself, or re-read + relayout), rather than relying on a kernel
signal that cannot arrive.

What Should Happen?

The attached background session's frame reflows to the new width/height, the way a foreground
session does.

Error Messages/Logs

Steps to Reproduce

  1. Start claude in a terminal and dispatch a background agent (claude --bg "...", or from agent

view).

  1. Run claude agents and attach to that background session.
  2. Resize the terminal window.

The frame keeps rendering at its startup size. In my case a 239-column frame inside a 479-column
pane — the input box border is drawn 239 wide with 240 columns of dead space to the right. It never
recovers, regardless of how long you wait or how many times you resize.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.232

Platform

Google Vertex AI

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗