[BUG] TUI input box leaves ghost renders in scrollback on tmux pane vertical resize

Resolved 💬 3 comments Opened Apr 24, 2026 by rollue Closed Apr 27, 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?

## Description

When Claude Code is running inside a tmux pane and the pane is resized vertically (shrunk
then expanded, or vice versa), the input box and status line leave ghost copies in tmux
scrollback. Expanding the pane back to a larger size reveals multiple stale input-box
renders interleaved with actual output, making prior console output unreadable.

The TUI appears to redraw its input box at the new bottom row on each SIGWINCH without
clearing the prior render region. Because tmux captures each intermediate frame into
scrollback as the pane shrinks, every intermediate input-box position becomes a permanent
artifact in history.

## Actual behavior

  • Start Claude Code in a tmux pane at some height H.
  • Resize pane smaller (e.g. drag divider up, or Prefix + Up repeatedly).
  • Each intermediate height produces a new input-box render at the new bottom row. Tmux

scrolls prior rows into history.

  • Resize pane back to height H (or larger).
  • Visible area now shows multiple stacked input boxes and status lines interleaved with

real output. The original output is effectively corrupted in scrollback — cannot be
recovered by Ctrl+L because Ctrl+L only redraws the visible screen, not scrollback
history.

Reproduces reliably. Does not reproduce for agent output itself — only for the persistent
bottom UI elements (input box, status line, footer).

## Environment

  • Claude Code: Opus 4.7 (1M context) session, latest CLI
  • OS: macOS Darwin 25.4.0 (Apple Silicon)
  • Terminal: tmux inside [iTerm2 / Ghostty / etc. — fill in]
  • tmux version: [run tmux -V and fill in]
  • Shell: zsh

## Impact

  • Scrollback is the primary way to review prior tool output, file reads, and agent

reasoning after long sessions. Corruption makes review impossible without restarting the
session.

  • Workflow cost: users must avoid resizing panes mid-session, or accept losing scrollback.
  • Especially painful with long-running agents or /loop tasks where scrollback is the

only record of intermediate state.

## Workaround

  • Ctrl+L redraws the visible screen but does not clean scrollback.
  • tmux Prefix + :clear-history wipes scrollback entirely — removes ghosts but

also removes all genuine output.

  • Prefix + z zoom/unzoom produces a single resize event and minimizes ghosts, but does

not eliminate them.

No workaround preserves scrollback while removing ghosts. Fix must be in the TUI render
path.

## Suggested fix

On SIGWINCH, before redrawing the input box / status line at the new bottom row, emit a
clear-to-end-of-screen (ESC[J) from the previous input-box start row, or track the
previous UI region and explicitly overwrite it with blanks. Alternatively, investigate
rendering persistent UI via a dedicated region (e.g. scroll region via ESC[r) so it
never enters scrollback.

What Should Happen?

On pane resize, the TUI should either:

  1. Clear the previous input-box region before redrawing at the new position, so scrollback

contains only genuine output, or

  1. Render the persistent UI (input box, status line, "auto mode" footer) on an alternate

screen buffer / via a mechanism that does not pollute scrollback, while keeping agent
output on the main buffer.

Scrollback should contain agent output only — not N copies of the input box captured
mid-resize.

Error Messages/Logs

⏺ No error messages or stack traces — this is a purely visual rendering artifact. No crash, no
  exception, no log entries produced.

  Claude Code continues functioning normally; only the tmux scrollback buffer is visually
  corrupted with duplicated input-box and status-line frames captured during pane resize.

Steps to Reproduce

⏺ ## Steps to reproduce

  1. Open iTerm2 (or any terminal emulator).
  2. Start a tmux session: tmux new -s repro.
  3. Launch Claude Code in the tmux pane: claude.
  4. Send a few prompts to generate enough output to fill the visible pane and push content

into scrollback (e.g. ls -la /usr, cat some-long-file.md).

  1. While Claude Code is idle at the input prompt, resize the tmux pane vertically smaller:
  • Split an adjacent pane: Prefix + " (horizontal split), or
  • Drag the pane divider up in iTerm2, or
  • Prefix + :resize-pane -U 10
  1. Resize the pane back to the original (or larger) height:
  • Prefix + :resize-pane -D 10, or drag divider back.
  1. Enter tmux copy-mode: Prefix + [, scroll up with PgUp / arrow keys.

Observed: Scrollback contains multiple stacked input-box frames, status lines, and
footer renders interleaved with the real agent output from step 4. Each intermediate pane
height during the shrink animation produced one ghost render.

Expected: Scrollback shows only the agent output from step 4, with a single (or zero)
input-box render at the point of resize.

### Minimal reproduction

``bash
tmux new -s repro \; send-keys 'claude' Enter
# wait for Claude Code to start, send one prompt, wait for response
# then in another terminal:
tmux resize-pane -t repro -U 15
sleep 1
tmux resize-pane -t repro -D 15
tmux attach -t repro
# Prefix + [ to inspect scrollback
``

Reproduces on every resize cycle. Ghost count scales with number of intermediate frames
rendered during the resize animation.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.118 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗