[BUG] Claude Code: Streamed-output rendering corruption on Ghostty + SSH

Resolved 💬 3 comments Opened Apr 30, 2026 by srangwal Closed May 4, 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?

When Claude Code streams a long markdown response (multiple code blocks,
headings, tables — roughly 2+ screenfuls), the rendered output becomes
visually corrupted partway through. Text from later in the response is
overdrawn on top of text from earlier in the same response, leaving
duplicated section headers and overlapping fragments visible on screen.

The actual textual content of the response is correct (copying from the
terminal yields clean text); only the on-screen rendering is wrong. The
corruption persists until the user resizes the window or otherwise forces
a full repaint.

This appears to be cursor-position bookkeeping inside the streaming
renderer drifting from the terminal's actual cursor state, so subsequent
draws land in already-occupied rows.

What Should Happen?

Streamed output should render incrementally with no overdraw of previously
rendered lines. As new content is appended at the bottom, older content
should scroll up cleanly, and the visible region of the terminal should
remain a consistent, sequential rendering of the message so far.

Error Messages/Logs

Steps to Reproduce

Reproduction is sporadic; I haven't found a fixed input that triggers it
100% of the time. Conditions that correlate with reproduction:

  1. SSH from a local Mac (running Ghostty terminal) into a remote Linux

host running Claude Code.

  1. Ask Claude a question whose response will be long — multiple sections,

2+ code blocks, a markdown table, and roughly 2+ screenfuls of output.

  1. Let the response stream to the terminal (do NOT scroll during streaming).
  2. Observe: somewhere mid-response, a section header that already scrolled

past the top of the visible area is redrawn on top of the current
bottom-of-screen content. The original section's content remains visible
below the duplicate header, so the screen now shows the same heading
and intro twice with different content following each.

Things present in the responses where I've reproduced this:

  • Fenced code blocks with syntax highlighting
  • Markdown tables
  • Mixed heading levels (## and ###)
  • Some non-ASCII characters: emoji (✅, ❌, ⚠️), box-drawing horizontal

rules (─ U+2500), en-dashes/em-dashes

  • Bullet lists nested inside other formatting

The bug does not appear consistently for short responses (single screen),
nor for purely-text responses without code blocks.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.123 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

Operating System

Linux (CBL-Mariner 2.0, kernel 5.15) on the remote host where Claude Code runs.
Local terminal host: macOS (Ghostty terminal). SSH connection between the two.

---
Terminal/Shell

Terminal: Ghostty (on macOS, locally)
Shell on remote: bash 5.1.8
TERM environment variable on remote: xterm-256color

---
A more detailed write-up is in the attached markdown file (or pasted below).
It covers:

  • Five hypothesized root causes ordered by likelihood
  • Six investigation steps for maintainers (cheapest-first), starting with

capturing the raw byte stream via script(1) and replaying against a
clean xterm

  • Workarounds I'm using until the fix lands

One specific data point worth flagging: the remote $TERM is "xterm-256color"
even though the local terminal is Ghostty. If Claude Code's renderer infers
terminal capabilities (e.g., wide-char width tables, supported escape
sequences) from terminfo, it may be using a generic xterm profile that
doesn't match Ghostty's actual rendering — which would explain why
line-wrap and cursor-position math drift over the course of a long stream.

Setting TERM=xterm-ghostty on the remote (if Ghostty's terminfo is
available there) and re-testing is the first thing I'd try to confirm or
rule out this hypothesis.

claude_code_rendering_bug.md

View original on GitHub ↗

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