Skip to content

BUG: Timeline scroll yanks user back to bottom on first session open #176

Description

@jeonghun-jj-lee

Summary

On first open of a session, scrolling up a couple of lines immediately snaps the viewport back to the bottom. The user cannot freely scroll away from the end until they close and reopen the session (at which point cached virtualizer measurements prevent the issue).

Context

  • Extension: harmoniqs.amicode 0.2.1
  • Engine: v1.18.10-amicode.4 (base v1.18.10)
  • OS: Darwin 25.5.0 arm64
  • Surface: message timeline virtualizer (packages/app/src/pages/session/timeline/message-timeline.tsx)

Expected vs actual

Expected: After the initial scroll-to-bottom on session open, the user should be able to scroll up freely — userScrolled disengages the auto-follow mechanisms.

Actual: Scrolling up a small amount (within ~80px of the bottom) is immediately reversed. The viewport snaps back to the absolute bottom. Only reproducible on first open of a session (no timelineCache); closing and reopening the same session works correctly.

Diagnostics
  • Suspected cause: followOnAppend: true combined with scrollEndThreshold: 80 in the virtualizer config. On first open, parts arrive asynchronously and append rows to timelineRows(). Since the user is within the 80px threshold, the virtualizer considers them "at the end" and auto-follows each appended row — overriding the userScrolled state. Note: this hypothesis has not been definitively confirmed — the true root cause may differ.
  • On re-open, timelineCache provides initialMeasurementsCache so no resize/append activity occurs and the bug vanishes.
  • A secondary issue: on cold-bottom-mount (no cached measurements), there is a one-frame flash of content at the top before scrollToEnd() fires in the onMount rAF.
  • Partial mitigations landed on branch jj/174-session-scoped-files-changed (PR Replace 'Files Changed' with session-scoped agent changes (#174) #175): reactive followOnAppend getter gated by shouldAnchorBottom(), and opacity hide during cold-bottom-mount. Not yet verified to fully resolve the symptom.

intake: not-ready — mature per the maturity contract before picking up
suggested_path: B
diagnostics: inline
upstream: none found (upstream repo not searchable)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions