claude-code - 💡(How to fix) Fix TUI rendering leaves stale characters at row edges during partial screen updates [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46898Fetched 2026-04-12 13:30:09
View on GitHub
Comments
2
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×4commented ×2closed ×1cross-referenced ×1

When Claude Code's TUI redraws the screen (e.g., during scrolling or navigation), it uses cursor positioning to skip columns at the beginning/end of rows without clearing them first. This leaves "ghost" characters from the previous frame visible at row edges.

Root Cause

When Claude Code's TUI redraws the screen (e.g., during scrolling or navigation), it uses cursor positioning to skip columns at the beginning/end of rows without clearing them first. This leaves "ghost" characters from the previous frame visible at row edges.

Fix Action

Workaround

Triggering a terminal resize (SIGWINCH) forces Claude Code to do a complete screen repaint, which clears all ghost characters. CLAUDE_CODE_NO_FLICKER=1 did not resolve this issue.

Code Example

bufferType: "alternate", cols: 138, rows: 28
Line 1: "Ge- 既有專案(有 project-context.md)""Ge" is stale from previous frame
Line 6: "Ap我需要了解你的需求""Ap" is stale from previous frame
RAW_BUFFERClick to expand / collapse

Description

When Claude Code's TUI redraws the screen (e.g., during scrolling or navigation), it uses cursor positioning to skip columns at the beginning/end of rows without clearing them first. This leaves "ghost" characters from the previous frame visible at row edges.

Reproduction

  1. Open Claude Code in any xterm.js-based terminal
  2. Wait for the TUI to render (e.g., memory context display, menu screens)
  3. Scroll or navigate to trigger a partial screen redraw
  4. Observe stale characters at the left and right edges of rows

Evidence

Buffer dump via terminal.buffer.active.getLine(n).translateToString() confirms the ghost text is in the xterm.js buffer itself — not a renderer artifact:

bufferType: "alternate", cols: 138, rows: 28
Line 1: "Ge- 既有專案(有 project-context.md)"   ← "Ge" is stale from previous frame
Line 6: "Ap我需要了解你的需求"                     ← "Ap" is stale from previous frame

The TUI positions the cursor to column ~2-3 and starts writing, leaving columns 0-1 with content from the prior render pass.

Cross-version verification

Tested with both xterm.js v5.5.0 and v6.0.0 — identical behavior on both versions. Also tested with both DOM renderer and @xterm/addon-canvas — same result. This confirms the issue is in the TUI's escape sequence output, not the terminal renderer.

Expected behavior

TUI should clear full rows before writing partial content, using either:

  • ESC[2K (erase entire line) before each row update
  • Write spaces to pad unused columns
  • ESC[2J (erase display) before full redraws

Workaround

Triggering a terminal resize (SIGWINCH) forces Claude Code to do a complete screen repaint, which clears all ghost characters. CLAUDE_CODE_NO_FLICKER=1 did not resolve this issue.

Environment

  • OS: Windows 11 Pro
  • Terminal: xterm.js 5.5.0 and 6.0.0 (Electron app)
  • Claude Code: 2.1.100
  • Renderers tested: DOM renderer, @xterm/addon-canvas 0.7.0

extent analysis

TL;DR

Clearing full rows before writing partial content using escape sequences like ESC[2K is likely necessary to fix the ghost character issue.

Guidance

  • Verify that the issue persists across different terminal renderers and xterm.js versions to confirm it's a TUI escape sequence output problem.
  • Consider implementing a workaround by triggering a terminal resize (SIGWINCH) to force a complete screen repaint, which clears ghost characters.
  • Investigate using ESC[2K to erase entire lines or writing spaces to pad unused columns before writing partial content.
  • Review the TUI's escape sequence output to ensure it's correctly handling row updates and full redraws.

Example

// Example of using ESC[2K to erase entire lines
function clearLine() {
  return '\x1B[2K'; // ESC[2K
}

Notes

The issue seems to be related to the TUI's escape sequence output, and not the terminal renderer. However, without more information about the TUI's implementation, it's difficult to provide a definitive solution.

Recommendation

Apply a workaround by using ESC[2K to clear entire lines before writing partial content, as this is a straightforward and effective solution to the ghost character issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

TUI should clear full rows before writing partial content, using either:

  • ESC[2K (erase entire line) before each row update
  • Write spaces to pad unused columns
  • ESC[2J (erase display) before full redraws

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING