Skip to content

[Bug]: iPad: a background thread finishing resets the visible thread's scroll position #15165

Description

@nekohasekai

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

  1. On iPad, use the split layout with the thread sidebar visible.
  2. Open thread A containing a response longer than the viewport.
  3. Switch to thread B and send a message.
  4. Return to A before B finishes. A opens near the end of its response.
  5. Without scrolling or interacting, wait for B to finish.

Expected behavior

A keeps its scroll position while another thread responds in the background.

Actual behavior

A jumps to the beginning around the time B changes from Working to Done. A remains selected.

Reproduced twice: once with B's first message and once with a follow-up in the same B. Switching between A and B without sending a message did not reset A during a 47-second control.

Impact

Major degradation or frequent failure

Version or commit

main @ 31a9da1

Environment

T3 Code Dev; iPad Pro 11-inch (M5) Simulator; iPadOS 26.5; landscape split layout; local backend; Codex provider using gpt-6-astra.

Logs or stack traces

A separate diagnostic run showed A's native scroll offset changing to 0 while its list identity and content dimensions remained unchanged. The exact cause is not yet confirmed.

Screenshots, recordings, or supporting files

Watch the 9-second reproduction (MP4)

Normal speed, with no cuts between switching to A and the reset. Recorded on an unmodified checkout using synthetic threads.

Workaround

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  2. added
    duplicateThis issue or pull request already exists
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  3. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks @nekohasekai for refiling this from #15162 with the template, and for the careful repro, the no-send control, and the diagnostic run. That last part (offset going to 0 with unchanged list identity and content size) was a big help. This looks like a real iOS scroll reset rather than a remount or LegendList adjusting for new rows.

    What's likely happening

    ThreadFeed scrolls through KeyboardAwareLegendList, which uses KeyboardChatScrollView. On main at 31a9da1 that's still react-native-keyboard-controller@1.22.4 with react-native-reanimated@4.7.0. In 1.22.4, ScrollViewWithBottomPadding leaves contentOffset out of the first useAnimatedProps evaluation, so Reanimated 4.7 treats a later keyboard-driven offset like a style. The next React commit of that list drops the prop, and Fabric resets the native offset to {0, 0}. That's the bug fixed upstream in kirillzyusko/react-native-keyboard-controller#1629 (merged).

    Sending a message on B opens the keyboard and arms this; your no-send control doesn't, which matches what you recorded. A jump to exactly 0 is that reset, not a scroll-to-end.

    One piece isn't pinned down yet: something still commits A's list around B's Working → Done transition. A's shell and details stay stable when only the other thread changes, and no feed path deliberately scrolls the open thread when another run settles, so the exact subscription hasn't been isolated.

    Likely fix area

    The open PR #14808 bumps the controller to 1.22.6, which includes contentOffset in the initial animated props. It's still going through review and would need a new native build. Checking this repro on that branch (A should keep its offset when B finishes) would show whether it covers this trigger too. A maintainer will decide on the fix direction.

  4. added
    via-triageFiled through npx t3 triage
    and removed
    duplicateThis issue or pull request already exists
    on Oct 3, 2026
  5. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Closing as a duplicate of #15162. That report is the canonical one (lower number); this issue was only a template refile for automatic labels. Triage is on #15162.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.duplicateThis issue or pull request already existsupstreamvia-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions