You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Client re-presents stale pane frames: every visible pane jumps to an older viewport position and snaps back, ~12 s cycle (follow-up to #2521/#283; reproduced on master) #2793
I confirm this is a reproducible bug, not a feature request, idea, question, contribution proposal, or direction check.
I reproduced this bug on the version and environment reported below using the exact steps provided.
Current behavior
Agent panes intermittently jump to an older viewport position and snap back, roughly every ~12 s, for 0.25–1.5 s each time. During the jump the pane shows the position of the start of the last user turn, together with a Jump to bottom (click) ↓ pill; then it returns to the bottom on its own.
The pill turns out to be the agent's own UI, not Herdr chrome: the string Jump to bottom exists in the Claude Code binary and is absent from both the herdr binary and every installed plugin. So the flashed frame is stale pane content — a frame the inner TUI drew at some earlier moment — being re-presented by the client and then corrected. That narrows the defect to the client re-presenting an out-of-date frame, consistent with the coordinate-diff analysis in #2521.
Key detail: it happens in every visible pane at the same time, including panes whose agent is idle and producing no output.
Measurements (macOS screencapture burst at 0.2 s, cross-checked against herdr pane read <pane> --source visible sampled in parallel):
13 flash events in 5 minutes, intervals clustering at ~11.7 / 12.3 / 12.1 s (longer gaps are exact multiples, i.e. events the detector missed).
The server-side buffer is unchanged during the flash: herdr pane read returns byte-identical output across the event. Only the rendered frame changes. This points at the client/render layer, not pane content.
The server-side scroll state is also unchanged: polling herdr pane list every 0.3 s for 90 s while the flashing was ongoing, scroll.offset_from_bottom stayed 0 for every pane the whole time. Buffer static + scroll static + pixels changing = the artifact lives entirely in the client's frame presentation.
This looks like the same defect described in #2521 (closed by bot for template reasons, not fixed) and originally in #283. That report's code-level analysis — src/protocol/render_ansi.rs::write_changed_cells() doing a coordinate-based cell diff with no scroll-region/insert-line awareness — is consistent with everything measured here.
Expected behavior
A pane that is following live output stays pinned to the bottom. The rendered frame should never briefly show a previous viewport position (nor the Jump to bottom pill) unless the user actually scrolled.
Reproduction
Open a workspace tab with 2–4 panes running an interactive agent (Claude Code here), each with a long transcript (several hours of history; short/fresh sessions reproduce far less often).
Focus that tab and leave the machine idle — no typing, no scrolling, no tab/space switching.
Watch for ~5 minutes, or capture frames: for i in $(seq 1 500); do screencapture -x -t jpg -R<x,y,w,h> f-$i.jpg; sleep 0.2; done
Detect events by looking for a large frame change that reverts to the previous frame within ~1.5 s (a plain dy shift detector will not catch it).
Ruled out here by direct measurement, in case it saves triage time:
[experimental] pane_history on and off — no difference.
Restarting the client, and restarting the server — no difference.
All 6 installed plugins disabled at once (herdr plugin disable), then a clean 5-minute observation window on the same tab (2026-08-13) — still flashes. Plugins are ruled out.
Focus events as trigger: injecting \e[O\e[I (focus-out/in) into a pane's PTY 8 times at 2 s intervals while watching it — no flash.
Same-size SIGWINCH as trigger: kill -WINCH on the agent process 8 times at 2 s intervals — no flash.
redraw_on_focus_gained = false — no difference.
External API calls (herdr agent list, herdr pane read, herdr pane list) fired at marked timestamps produced no flash, so third-party API polling is not the trigger.
Idle panes do not leave follow mode on their own (offset_from_bottom stayed 0 over 3 minutes), and neither pane zoom nor pane split (a real 45→22 row resize) knocked a pane out of follow.
Not yet determined: whether it reproduces with plain shell panes and no agent attached. My attempt at that test was contaminated (the panes had been scrolled manually), so I am reporting it as open rather than claiming it.
One possibly related observation: herdr plugin log shows pane.focused events firing repeatedly while the user is not switching panes.
Screenshots are omitted because the panes contain patient data (the user is a physician). I can reproduce and attach redacted or synthetic-content captures on request.
Impact
Continuous, on every visible agent pane, during normal work. Text becomes hard to read because the pane keeps jumping to an older position and back while you are reading it. The only workaround found is zooming a single pane (prefix+z), which reduces exposure but does not fix the underlying behavior.
Environment
Herdr version: 0.8.0 stable (Homebrew) AND master b710176 (2026-08-13) — identical behavior on both
Operating system: macOS 27.0 (Darwin 27.0.0), Apple Silicon
Terminal: Ghostty
Shell: zsh
Agent: Claude Code 2.1.232 (runs in alternate screen; panes therefore report no scrollback)
Is this a reproducible bug?
Current behavior
Agent panes intermittently jump to an older viewport position and snap back, roughly every ~12 s, for 0.25–1.5 s each time. During the jump the pane shows the position of the start of the last user turn, together with a
Jump to bottom (click) ↓pill; then it returns to the bottom on its own.The pill turns out to be the agent's own UI, not Herdr chrome: the string
Jump to bottomexists in the Claude Code binary and is absent from both theherdrbinary and every installed plugin. So the flashed frame is stale pane content — a frame the inner TUI drew at some earlier moment — being re-presented by the client and then corrected. That narrows the defect to the client re-presenting an out-of-date frame, consistent with the coordinate-diff analysis in #2521.Key detail: it happens in every visible pane at the same time, including panes whose agent is idle and producing no output.
Measurements (macOS
screencaptureburst at 0.2 s, cross-checked againstherdr pane read <pane> --source visiblesampled in parallel):herdr pane readreturns byte-identical output across the event. Only the rendered frame changes. This points at the client/render layer, not pane content.herdr pane listevery 0.3 s for 90 s while the flashing was ongoing,scroll.offset_from_bottomstayed0for every pane the whole time. Buffer static + scroll static + pixels changing = the artifact lives entirely in the client's frame presentation.dyalignment between consecutive frames) is blind to it — the whole pane region changes, which matches the coordinate-based diff analysis in Interactive agent output (menu/prompt) causes viewport to scroll up then snap back — coordinate-based diff, not scroll-region aware (follow-up to #283) #2521.This looks like the same defect described in #2521 (closed by bot for template reasons, not fixed) and originally in #283. That report's code-level analysis —
src/protocol/render_ansi.rs::write_changed_cells()doing a coordinate-based cell diff with no scroll-region/insert-line awareness — is consistent with everything measured here.Expected behavior
A pane that is following live output stays pinned to the bottom. The rendered frame should never briefly show a previous viewport position (nor the
Jump to bottompill) unless the user actually scrolled.Reproduction
for i in $(seq 1 500); do screencapture -x -t jpg -R<x,y,w,h> f-$i.jpg; sleep 0.2; donedyshift detector will not catch it).Ruled out here by direct measurement, in case it saves triage time:
[experimental] pane_historyon and off — no difference.herdr plugin disable), then a clean 5-minute observation window on the same tab (2026-08-13) — still flashes. Plugins are ruled out.\e[O\e[I(focus-out/in) into a pane's PTY 8 times at 2 s intervals while watching it — no flash.kill -WINCHon the agent process 8 times at 2 s intervals — no flash.redraw_on_focus_gained = false— no difference.herdr agent list,herdr pane read,herdr pane list) fired at marked timestamps produced no flash, so third-party API polling is not the trigger.offset_from_bottomstayed 0 over 3 minutes), and neitherpane zoomnorpane split(a real 45→22 row resize) knocked a pane out of follow.Not yet determined: whether it reproduces with plain shell panes and no agent attached. My attempt at that test was contaminated (the panes had been scrolled manually), so I am reporting it as open rather than claiming it.
One possibly related observation:
herdr plugin logshowspane.focusedevents firing repeatedly while the user is not switching panes.Screenshots are omitted because the panes contain patient data (the user is a physician). I can reproduce and attach redacted or synthetic-content captures on request.
Impact
Continuous, on every visible agent pane, during normal work. Text becomes hard to read because the pane keeps jumping to an older position and back while you are reading it. The only workaround found is zooming a single pane (
prefix+z), which reduces exposure but does not fix the underlying behavior.Environment
tab_bar_position = "top",pane_scrollbars = false,show_agent_labels_on_pane_borders = true,agent_panel_sort = "priority",[ui.toast] delivery = "terminal",[experimental] pane_history = true(default restored after testing)