[Bug] Scroll position jumps when Claude streams output during upward scrolling

Resolved 💬 37 comments Opened Mar 11, 2026 by jkaster Closed Apr 26, 2026
💡 Likely answer: A maintainer (claude[bot], contributor) responded on this thread — see the highlighted reply below.

Bug Description
you've introduce a bug with scrolling jitter when scrolling up through conversation history. while Claude is displaying new results, if I scroll up now my scroll position jumps around and I often get put to the top of the scroll buffer so I can never even read the recent output from Claude Code that has scrolled past the current screen

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.73
  • Feedback ID: 30867ea8-0488-42c1-8e25-f9681c2cabe9

View original on GitHub ↗

37 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/826
  2. https://github.com/anthropics/claude-code/issues/21631
  3. https://github.com/anthropics/claude-code/issues/18299

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

binaryfire · 4 months ago

Same. This bug was fixed, and now it's back.

ijstokes · 4 months ago

Oh this is so painful. Yes, it worked fine until at least 2.1.71 (earlier this week), and then somewhere between there and 2.1.74 if I've scrolled up even just a little to look at some output or comments and new output is produced "lower down" then my viewport jumps TO THE VERY BEGINNING. My Claude Code sessions go on for days. There are 10s of THOUSANDS of lines I then need to scroll back down through to get to the "right now", and in fact I don't even want to be at the "right now", I need to be reading the output from the current agent session which might be taking 3-5-10 minutes to complete, but I want to track and see what is happening so I can think about it, form next step questions, and exceptionally, if needed, stop it from proceeding. But can I do any of that right now? So far as I can tell: no. I have to scroll up quickly, get a glimpse of what is there on the screen from output I need to grok from the last few minutes (and sometimes for reference from earlier finished interactions & agent actions), before more output is produced which will kick me to the top of the terminal session. Ugh. Please fix. I can't believe more people haven't found this issue to upvote it.

jakeg · 4 months ago

This is _really_ annoying and makes it impossible to read what Claude just said as I have to try to hold the scroll bar in a particular position then it jumps to somewhere else.

Unlike the op, I'm on Windows in PowerShell.

VoxCore84 · 4 months ago

We hit this too and collected working workarounds into a repo: claude-code-scroll-fix

Quick fix (Windows Terminal): Add "snapOnOutput": false to your profiles.defaults in settings.json. Reduces jumping ~60-70%.

Complete fix: Run Claude inside tmux — it completely decouples your scroll position from Claude's cursor repositioning. The repo has a one-click installer that sets up WSL + tmux + a Windows Terminal profile.

Root cause: Claude Code uses CSI escape sequences to rewrite the thinking spinner in-place, and terminals follow the cursor position back up. snapOnOutput only fixes output-triggered scrolling, not cursor repositioning — tmux fixes both.

jaywonchung · 4 months ago

Getting this on Claude Code 2.1.76, MacOS 26.3, and Ghostty 1.3.0 as well.

FurbySoup · 4 months ago

This is the same root cause as #826 — Claude Code's full screen redraws reset scroll position.
https://github.com/FurbySoup/quell is a Windows proxy that fixes this by stripping the clear-screen from redraw sync blocks. quell claude and it just works.

Crazytieguy · 4 months ago

Hands down the most annoying bug in claude code history imo

ttibbetts · 4 months ago

Confirming the same behavior on Windows Terminal + PowerShell. When scrolled up to review conversation history while Claude is actively streaming a response, the viewport jumps to the very top of the session. This feels like a recent regression - I wasn't experiencing it consistently before.
Claude Code version: 2.1.76
OS: Windows 11 on ARM
Terminal: Windows Terminal + PowerShell
Noting that the same core symptom has been reported on Windows previously (#1486, #22988, #24790) but those were all bot-closed.

gamenerds · 4 months ago

guys I will lose my mind if you don't prioritize fixing this. THIS AFFECTS EVERYONE!!! Who gives a fk about your thinking indicator if it's causing this issue (assuming you can't have both the fix and thinking indicator). Dev QOL > everything.

synergy49 · 4 months ago

Confirming the same behavior on Windows Terminal + PowerShell.; IT IS SUPER ANNOYING.

synergy49 · 4 months ago

FIX THISSSSSS!!!!!!

synergy49 · 4 months ago

It happens with powershell, and vs code, in windows.

ethanyzhang · 4 months ago

+1

cruzlauroiii · 4 months ago

A fix for this is available as a Claude Code plugin: https://github.com/anthropics/claude-code/pull/35683

The scroll-fix plugin clamps cursor-up sequences within synchronized output blocks to the viewport height, preventing the terminal from scrolling to the top. Also includes Ctrl+6 freeze toggle for manual scroll control. Works on all platforms and terminals.

senguttuvang · 4 months ago

Confirming on macOS (Darwin 25.3.0) + iTerm2. This is the single most disruptive UX issue in Claude Code.

The compound effect with autocompaction makes this worse than a scroll bug:

  1. Viewport jumps to the top while Claude is streaming → can't read output in real-time
  2. Autocompaction fires → terminal scrollback is wiped (see #34718)
  3. Post-compaction, there's no TUI path to review what was lost (see #27242)

The net result: important output (architectural decisions, test results, error messages) passes through the terminal in a window of a few seconds, and if you don't catch it in that moment, it's gone from the UI permanently. The only fallback is parsing raw transcript.jsonl with jq.

These three issues form a pipeline that ensures users can never reliably read Claude's output:

  • #33367 (this issue) — can't read during streaming (scroll jumping)
  • #34718 — can't read after compaction (scrollback wiped)
  • #27242 — can't read historically (no TUI access to pre-compaction content)

Fixing the scroll jumping alone would be a massive improvement — at least users could read output before compaction erases it.

Environment: macOS 26.3, iTerm2, Claude Code latest, Opus 4.6 (1M context)

cruzlauroiii · 4 months ago

A fix is available as a Claude Code plugin: scroll-fix

Install:

/plugin marketplace add cruzlauroiii/claude-code
/plugin install scroll-fix@cruzlauroiii-plugins

Root cause: both Ink renderer AND readline/prompt system emit cursor-up sequences exceeding viewport height. The plugin clamps all cursor-up per write call. Also includes Ctrl+6 freeze toggle.

PR: https://github.com/anthropics/claude-code/pull/35683

laughingmanzero · 4 months ago

Additional Findings from Extensive Troubleshooting

Spent two days debugging this across multiple configurations. Confirming this is a Claude Code rendering issue, not terminal/multiplexer config.

What we tested:

  1. tmux with mouse on — jumps to top of scrollback buffer ❌
  2. tmux removed entirely (native iTerm2 splits) — still jumps ❌
  3. iTerm2 "Scroll To Bottom On Output" = off (verified via defaults read) — still jumps ❌
  4. tmux history-limit 50000 — no change ❌
  5. tmux copy-mode unbindings — broke keyboard shortcuts, no scroll fix ❌
  6. iTerm2 "Disambiguate Escape" toggle — no change ❌
  7. iTerm2 full reset to factory defaults — still jumps ❌
  8. iTerm2 "Always Deny" for clear scrollback escape — no change ❌

The Smoking Gun

After resetting iTerm2 to defaults, iTerm2 displayed a permission prompt:

"A control sequence attempted to clear scrollback history. Allow this in the future?"

This confirms Claude Code is emitting scrollback-clearing escape sequences. However, denying the permission did not stop the jumping — the cursor-up overflow is the primary vector.

Root Cause Confirmation

Aligns with PR #35683 — Ink renderer + readline emit cursor-up sequences exceeding viewport height.

Environment

  • macOS: 26.3.1 (Build 25D771280a)
  • iTerm2: 3.6.9 (Build 3.6.9)
  • Claude Code: 2.1.78
  • tmux: 3.6a (tested both with and without)
  • Hardware: Apple Mac Mini M4, Samsung Odyssey G95NC ultrawide (5120x1440)
  • Shell: zsh 5.9

Plugin

Installed scroll-fix@cruzlauroiii-plugins per PR #35683 recommendation. Will report results after next session restart.

Update: still no fix after plugin, all that's changed is that cursor still jumps to top of window, but now there's some kind of frankenstein-inserting of the latest lines in the view. Ctrl + 6 seemed to help for a moment, then stopped working or doing anything. Just giving up on this entirely until resolved.

jonaselkabouli · 3 months ago

Same issue here on macOS (Darwin 23.6.0) in terminal. Scrolling up to read earlier output while Claude is responding jumps to the very top of the session. Happens consistently, especially during long sessions with many tool calls. Would love a fix — even a simple 'lock scroll position while user is scrolled up' would solve it.

felipekj · 3 months ago

+1 — experiencing this on GNOME Terminal (same behavior as IntelliJ terminal). Cursor randomly scrolls up during streaming output.

AlexandreL04 · 3 months ago

+1 same behavior as a Windows user, for all terminals available.

freak4pc · 3 months ago

Absolutely making me lose my mind :) The time I like to read the history is right when CC generates stuff, and every new piece of code pushes the viewport all the way down

jelsco · 3 months ago

v2.1.81 still getting it, this is maddening

ethanyzhang · 3 months ago

It’s hard to believe this issue is stuck here for this long… don’t they use Claude code themselves and not experiencing the same annoying issue?

nullbio · 3 months ago
It’s hard to believe this issue is stuck here for this long… don’t they use Claude code themselves and not experiencing the same annoying issue?

They probably don't read the code or the output. Explains the quality control.

synergy49 · 3 months ago

Definitely is a deal breaker, awful experience.

sstraus · 3 months ago

👍 We're experiencing the same issue embedding xterm.js 6.0.0 in a Tauri app. The scroll position jumps when Claude Code redraws its TUI while the user is scrolled up. Confirmed root cause: cursor-up sequences exceeding viewport height + ESC[2J/ESC[3J.

haikalpribadi · 3 months ago

I'm loosing my mind cause of this bug.

VoxCore84 · 3 months ago

Consolidated root-cause analysis across all 4 scrolling issues (#33367, #33814, #10835, #34242) plus related reports (#34400, #34052):

The root cause has been independently identified by multiple users. Credit to @doitallwrong (on #33814) for the most precise technical analysis:

Three specific functions in cli.js emit cursor-up ANSI sequences (\x1b[nA) where n equals the previous render height — which can be hundreds or thousands of lines. Terminals follow the cursor to the new position (above the visible viewport), causing the viewport to jump to the top.

  1. HF7() — Ink renderer clear
  2. Two copies of eraseLines — prompt renderer

None of these clamp n to the viewport height. @doitallwrong provided a 3-line sed patch that fixes the issue at the source by clamping the cursor-up sequences.

An aggravating factor on Windows: microsoft/terminal#14774 causes SetConsoleCursorPosition to scroll the viewport even inside synchronized update blocks.

Workaround effectiveness ranking (from our testing + community reports):

| Workaround | Effectiveness | Platform | Notes |
|---|---|---|---|
| sed patch on cli.js (@doitallwrong) | ~95% | All | Most surgical, but breaks on update |
| tmux | ~80% | macOS/Linux | Works for most but not all users (@duerra, @laughingmanzero report failures) |
| snapOnOutput: false in Windows Terminal | ~60-70% | Windows only | Reduces frequency but doesn't eliminate |
| claude-chill Rust PTY proxy | Unknown | macOS | Limited testing |
| @cruzlauroiii plugin (PR #35683) | Mixed | All | Install broken due to npm namespace reservation |
| Type a letter without sending | ~30% | Terminal-dependent | Bandaid |

Current status:

  • @bogini (Anthropic) is assigned to #33367 and #33814
  • Mar 25 changelog mentions "Fixed scrollback jumping when collapsed read/search groups finish" and "Fixed scrollback jumping to top when model starts or stops thinking" — but no user has confirmed this resolves the core issue
  • 61+ thumbs-up on this issue alone, 100+ across all duplicates
  • Zero Anthropic employee comments on any of the 6 related issues

The fix is known and small (clamp cursor-up to viewport height). The impact is massive (this is the most-reported UX bug in the repo by combined upvotes). The sed patch proves it's a ~3 line change.

sstraus · 3 months ago

We've been fighting this exact issue in TUICommander (a terminal orchestrator for AI coding agents built on xterm.js) for about two weeks. Here's a summary of what we tried:

Failed approaches

| # | Approach | Result |
|---|----------|--------|
| 1 | Strip ESC[2J/ESC[3J — replace ESC[2J with ESC[H ESC[J, strip ESC[3J entirely | Broke Claude Code's rendering — CC depends on these for its TUI redraws |
| 2 | afterWrite scroll restore — snapshot scroll position before write, restore after | Overridden by xterm's internal rAF sync — the restore gets clobbered one frame later |
| 3 | VT100 DiffRenderer — process PTY output through vt100 parser, emit minimal screen diffs instead of raw escape sequences | Incompatible with scrollback — works for alt-screen only |
| 4 | Reverted everything — strip + afterWrite caused more problems than they solved |

Current mitigation (~85-90%)

| # | Approach | Result |
|---|----------|--------|
| 5 | Write-based viewport lock — distinguish programmatic vs user-initiated scroll by tracking whether a write is in progress. Programmatic scrolls during writes → restore position. User scrolls outside writes → respect user intent | Works for most cases. Key insight: the write boundary is the reliable signal |
| 6 | Guard anchor=0 — renderer rebuilds (texture atlas refresh, font size changes) fire transient scroll events reporting position 0. Ignore these when scrollback exists | Fixes a specific jump-to-line-0 variant |
| 7 | Guard disengage during write — xterm reports "at bottom" during writes (because it auto-scrolls internally), which fools the lock into disengaging. Refuse to disengage while a write is in progress | Fixes the lock getting dropped by xterm's own internal scroll |

New: cursor-up clamping (your approach)

Based on @doitallwrong's analysis, we've now added ESC[nA / ESC[nF clamping in the PTY data path before it reaches xterm.js. Each session tracks its viewport rows (updated on resize). Before emitting PTY output, ESC[nA and ESC[nF are clamped to min(n, viewport_rows).

This is a different approach from what we tried before — we previously targeted ESC[2J/3J (clear commands), not the cursor movement sequences themselves. Combined with the viewport lock (approaches 5-7) as defense-in-depth.

This will ship in TUICommander v0.9.9 nightly. We'll report back with results after testing with Claude Code, Codex, and Aider sessions.

The upstream fix (clamping in cli.js) would still be the right long-term solution — terminal emulators shouldn't need to compensate for this.

FurbySoup · 3 months ago

@VoxCore84's breakdown is the best root cause analysis I've seen on this — the three-sequence identification matches exactly what I found building a fix for this. Wanted to share where that ended up and genuinely curious whether it helps people's specific setups.

Quell is a Windows terminal built specifically for Claude Code. It intercepts VT output via ConPTY and strips the sequences responsible for the scroll-jumping before they ever reach the renderer.

What it fixes (as of v0.2.1):

All three root causes now handled:

  • ESC[3J — erase scrollback — stripped unconditionally
  • ESC[2J — erase display — stripped outside DEC 2026 synchronized update blocks (allowed inside, where it's part of an atomic redraw)
  • ESC[nA — cursor-up — stripped outside sync blocks (v0.2.1, shipped two days ago)

The sync-block awareness matters for the latter two: Ink wraps its redraws in BSU/ESU markers, so we can distinguish "this is a legitimate UI repaint" from "this is orphaned cursor movement that will snap the viewport." The sed patch approach strips cursor-up unconditionally — which works, but also strips legitimate cursor movement. Our approach is more surgical.

Two ways to use it:

GUI (recommended — eliminates the problem entirely): A standalone terminal app — download the installer. Because we own the renderer (xterm.js), the cursor-up issue has nowhere to propagate to. This is the cleanest fix.

CLI proxy: For people who want to stay in their current terminal — quell claude wraps Claude Code in the filter layer. Handles ESC3J and ESC[2J completely. Cursor-up handling helps significantly, though in very long sessions you may still see minor drift from [microsoft/terminal#14774 — that's an upstream terminal behaviour we can mitigate but not fully control from a proxy position.

What I'd genuinely like to know:

Does this actually solve it for people's real sessions? The cases I'm most uncertain about are very long sessions (1000+ line scrollback) and heavy tool-use sequences where Ink redraws rapidly. If anyone tries it and finds cases where the jumping still occurs, I'd like to understand exactly what's happening — logs, repro steps, whatever's useful.

Also — now that Claude Code is 'open source', I'm looking at whether proposing that Ink adopt sync markers more consistently is viable. That would make the proxy approach essentially lossless for both CLI and GUI users. If anyone's interested in that angle, happy to discuss.

Windows only for now (ConPTY is the core of the fix). MIT licensed, no telemetry.

GuanglinDu · 3 months ago

@haikalpribadi , please try Qell as a workaround to solve this problem if you're on Windows. I succeeded this way on Windows 10 with PowerShell PSVersion 5.1.19041.3031.

parsakhaz · 3 months ago
this is a huge issue. love claude code but this makes it really really hard to use

hey. it's fixed at the terminal level here

https://github.com/Dcouple-Inc/Pane/pull/120

open source, using xtermjs which is the same terminal as VS Code. feel free to copy this fix or download the latest release to run claude code on any operating system with the fix in place. i was so mad and frustrated at this that I had to fix it myself.

Not just a scrolling issue — also a rendering/layout problem in VS Code's side-by-side panel mode. When Claude Code runs in VS Code with the terminal on one side and the editor on the other, text formatting breaks in unpredictable ways. Options and multi-line output get weirdly split left-right, text wraps incorrectly, and the whole experience feels janky rather than fluid. Combined with the scroll-jumping, longer sessions in VS Code become genuinely hard to follow. This isn't just macOS standalone terminal — it's very much a VS Code integrated terminal issue too.

yeah i had to switch off cursor/vscode and build myself an ide that managed xtermjs (the library they both use) well enough for the complex TUIs to not break.

works great and i have a fix for the scroll jump i just implemented rn here

https://github.com/Dcouple-Inc/Pane/pull/120

parsakhaz · 3 months ago

because its terminal level fix, it works with git bash, powershell, cmd, macs terminals on Pane. FYI.

claude[bot] contributor · 2 months ago

This is a duplicate of #35403, which was fixed as of version 2.1.101.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.