[Bug] Scroll position resets to top during agent execution

Status Closed — duplicate
Reported on v2.1.76
Maintainer reply ✓ Yes — claude[bot]
Activity 14 comments · opened Mar 14, 2026 · closed Apr 26, 2026
💡 Likely answer: A maintainer (claude[bot], contributor) responded on this thread — see the highlighted reply below.

Bug Description
when the agent is working, I scroll to view the previous content, then the scroll view is reset to top position, expect to maintain at where I am scrolling.

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.76
  • Feedback ID: af9d0228-569e-4113-9533-a89e8deeb1a0

Note: Content was truncated.

View original on GitHub ↗

14 Comments

VoxCore84 · 5 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.

cruzlauroiii · 5 months ago

Confirmed same behavior on Windows Terminal + PowerShell (v2.1.76). Filed #34794 with Windows-specific details. This affects multiple platforms (macOS iTerm, Windows Terminal, WSL2) — likely a core rendering/cursor issue in the CLI output layer.

cruzlauroiii · 5 months ago

Root cause traced in cli.js v2.1.76 source: Ink's rendering uses \ on every re-render. When output is large, the cursor moves far up in the buffer and Windows Terminal (and iTerm) follows the cursor, snapping the viewport to the top. Full analysis in #34794.

cruzlauroiii · 5 months ago

Updated PR #34798 with v2 fix: stateful stdout.write interceptor that clamps cursor-up across ALL writes (not just sync blocks). Catches Ink renderer, prompt renderer, and all other cursor-up sources. Patch + PowerShell script included.

cruzlauroiii · 5 months ago

Updated PR #34798 with 3 combined patches: (1) stateful stdout.write interceptor clamping cursor-up, (2) render throttle 16ms→200ms, (3) disable synchronized update mode. All three are needed — cursor-up clamping alone does not fix it because Windows Terminal exits scroll mode on ANY stdout write, and sync blocks batch writes into one viewport-resetting update. PowerShell apply/revert script included.

cruzlauroiii · 5 months ago

v3 update: Previous fixes (cursor-up clamping, disabling sync update) did not work and caused flickering.

Root cause identified: Windows Terminal bug microsoft/terminal#14774SetConsoleCursorPosition always scrolls viewport to cursor, even when visible. Every Ink re-render triggers this. Cannot be fixed from within the process.

v3 patch: render throttle SK6=16SK6=1000 (1fps). Gives 1 second of uninterrupted reading between viewport resets. Trade-off: streaming text in ~1s chunks. No flickering.

PR #34798 updated. Real fix needs Microsoft (terminal#14774) or Anthropic (PTY proxy/append-only rendering).

cruzlauroiii · 5 months ago

v5 update: Fundamentally different approach — buffer ALL Ink renders during active work, screen stays frozen (no viewport jumping). Flush only when (a) user types (at prompt/bottom, safe to update) or (b) 5s of no renders (Claude finished). Previous v1-v4 failed because WT bug microsoft/terminal#14774 triggers viewport scroll on ANY cursor positioning. v5 avoids this by not writing to stdout at all during active work. Trade-off: no spinner/progress visible during work. PR #34798 updated.

cruzlauroiii · 5 months ago

v6: Buffer ALL renders, flush ONLY on user input (stdin). No timer. No auto-flush. Zero viewport jumping while not at bottom. Root cause: WT bug microsoft/terminal#14774. PR #34798.

cruzlauroiii · 5 months ago

v7: Replay ALL buffered frames on flush (fixes v6 outdated screens). Keeps entire diff chain so screen content is always correct. Still zero viewport jumping — flush only on user input (stdin). PR #34798.

cruzlauroiii · 5 months ago

Final fix: Ctrl+6 freeze toggle. Press Ctrl+6 to freeze screen (buffer renders, scroll freely). Press again to unfreeze (replay + live output). Tab title shows [FROZEN]. Root cause is WT bug microsoft/terminal#14774 — cannot be detected/fixed automatically. PR #34798.

sasha-id · 5 months ago

try this

### iTerm2 Global Settings
AppleScrollAnimationEnabled = 0
NSScrollAnimationEnabled = False
NSScrollViewShouldScrollUnderTitlebar = False

### iTerm2 tmux Profile (scroll-related)
| Setting | Value |
|---------|-------|
| Scroll To Bottom On Output | False |
| Scrollback Lines | 3000 |
| Scrollback in Alternate Screen | False |
| Scrollback With Status Bar | False |
| Allow Alternate Mouse Scroll | True |
| Mouse Reporting | False |
| Disable Window Resizing | True |

### tmux Config (~/.config/.tmux.conf)
```bash
set -g alternate-screen off # let iTerm2 handle screen switching
# set -ga terminal-overrides ',xterm*:smcup@:rmcup@' # disabled

claude[bot] contributor · 4 months ago

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

github-actions[bot] · 3 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.