[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
37 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Same. This bug was fixed, and now it's back.
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.
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.
We hit this too and collected working workarounds into a repo: claude-code-scroll-fix
Quick fix (Windows Terminal): Add
"snapOnOutput": falseto yourprofiles.defaultsinsettings.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.
snapOnOutputonly fixes output-triggered scrolling, not cursor repositioning — tmux fixes both.Getting this on Claude Code 2.1.76, MacOS 26.3, and Ghostty 1.3.0 as well.
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.
Hands down the most annoying bug in claude code history imo
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.
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.
Confirming the same behavior on Windows Terminal + PowerShell.; IT IS SUPER ANNOYING.
FIX THISSSSSS!!!!!!
It happens with powershell, and vs code, in windows.
+1
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.
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:
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.jsonlwithjq.These three issues form a pipeline that ensures users can never reliably read Claude's output:
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)
A fix is available as a Claude Code plugin: scroll-fix
Install:
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
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:
mouse on— jumps to top of scrollback buffer ❌defaults read) — still jumps ❌history-limit 50000— no change ❌The Smoking Gun
After resetting iTerm2 to defaults, iTerm2 displayed a permission prompt:
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
Plugin
Installed
scroll-fix@cruzlauroiii-pluginsper 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.
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.
Still broken as of v2.1.81:
https://github.com/anthropics/claude-code/issues/36582
https://github.com/anthropics/claude-code/issues/35403
https://github.com/anthropics/claude-code/issues/36816
https://github.com/anthropics/claude-code/pull/35683
https://github.com/anthropics/claude-code/issues/33814
https://github.com/anthropics/claude-code/issues/34845
https://github.com/anthropics/claude-code/issues/33367
https://github.com/anthropics/claude-code/issues/34400
https://github.com/anthropics/claude-code/issues/826
https://github.com/anthropics/claude-code/issues/36621
https://github.com/anthropics/claude-code/issues/36128
https://github.com/anthropics/claude-code/issues/35766
https://github.com/anthropics/claude-code/issues/34242
https://github.com/anthropics/claude-code/issues/18299
+1 — experiencing this on GNOME Terminal (same behavior as IntelliJ terminal). Cursor randomly scrolls up during streaming output.
+1 same behavior as a Windows user, for all terminals available.
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
v2.1.81 still getting it, this is maddening
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.
Definitely is a deal breaker, awful experience.
👍 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.
I'm loosing my mind cause of this bug.
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.jsemit cursor-up ANSI sequences (\x1b[nA) wherenequals 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.HF7()— Ink renderer cleareraseLines— prompt rendererNone of these clamp
nto the viewport height. @doitallwrong provided a 3-linesedpatch that fixes the issue at the source by clamping the cursor-up sequences.An aggravating factor on Windows: microsoft/terminal#14774 causes
SetConsoleCursorPositionto scroll the viewport even inside synchronized update blocks.Workaround effectiveness ranking (from our testing + community reports):
| Workaround | Effectiveness | Platform | Notes |
|---|---|---|---|
|
sedpatch 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: falsein Windows Terminal | ~60-70% | Windows only | Reduces frequency but doesn't eliminate ||
claude-chillRust 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:
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
sedpatch proves it's a ~3 line change.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[nAandESC[nFare clamped tomin(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.@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 unconditionallyESC[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 claudewraps 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.
@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.
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.
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
because its terminal level fix, it works with git bash, powershell, cmd, macs terminals on Pane. FYI.
This is a duplicate of #35403, which was fixed as of version 2.1.101.
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.