Skip to content

[Bug]: iOS: long thread jumps far above the latest message while the app is open #15469

Description

@goleary

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

Frequent, several times per session in long threads, under many circumstances. Two I've confirmed:

  1. On the iOS app, open a long thread (hundreds of messages, many tool calls and images) and scroll to the bottom.
  2. Either:
    • Idle: leave the thread open in the foreground without touching it (no scrolling, typing or sending), with no agent reply in progress; or
    • After sending: send a message.
  3. The timeline jumps far up on its own: at some point while idle, or right after the message is sent.

In the idle case there is no scroll gesture, no sent message and no streaming content, so something other than user input or new output moves the list.

Expected behavior

While I'm at the bottom of the thread, the view stays at the latest message.

Actual behavior

The view jumps well above the latest message and stays there, so I have to scroll back down to reach the end. This is not a stale position restored on returning to the app or thread (as in #13601 / #14051); it happens while I'm actively using the app.

Impact

Major degradation or frequent failure

Version or commit

iOS app: v1.4.0. Desktop host: T3 Code (Alpha) 0.0.45.

Environment

iPhone 14 Pro, iOS 26.7. Desktop host on Windows 11 Pro. Provider: Claude Code (Opus 5.5).

Logs or stack traces

None captured.

Screenshots, recordings, or supporting files

I have a 16.7 s screen recording of one occurrence (after sending) and will attach it. Frame-by-frame:

  • 0–6 s: I scroll by finger from an older part of the thread down to the bottom, then stop. The view is pinned at the bottom.
  • 8 s: I send a short message. The keyboard dismisses and the composer collapses to one line; the message shows as Pending.
  • 9–10.5 s: A "Thinking" row and a "Working for 0s / 1s" pill appear. The view stays correctly pinned to the bottom. I'm not touching the screen.
  • 11.0 s: In a single frame, as the timer reaches "Working for 2s", the view jumps roughly 5+ screens up, to messages from about 3.5 hours earlier. The row it lands on contains an image that is briefly a gray placeholder while it reloads. No scroll-to-end button is shown for the next second or so; it appears at about 12.5 s, once the run ends.
  • 13–13.5 s: I scroll back down to the bottom, and it stays pinned for the rest of the recording.

The jump coincides with the keyboard dismissing, the composer shrinking and the Thinking row appearing within about three seconds of sending, with no streaming text yet.

Notably, it lands on the same older message I had been scrolled to at the start of the recording, before I scrolled down by hand ("i prefer no color by default like keep.", 6:03 PM). So it looks like the list snaps back to a position or anchor it held earlier in the session, rather than to an arbitrary offset.

Related

Workaround

Scroll down manually or tap "Scroll to end".

Activity

  1. juliusmarminge commented on Oct 4, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks @goleary for the detailed frame-by-frame breakdown and the idle case. That timing is really useful. This looks like a real bug, and it isn't a duplicate of the reports you linked. #13601, #14051 and #12372 are about a saved position being restored when you return to or switch threads, and #5903 is the web client opening or finishing above the end. Here the jump happens while the thread stays on screen.

    What I found

    • A known iOS jump that 1.4.0 still ships with. App 1.4.0 depends on react-native-keyboard-controller 1.22.4. After the composer keyboard has opened on a screen, a later render of the feed can drop contentOffset, and Fabric resets it to 0, so the feed jumps to the very first message. That was fixed by fix(mobile): iOS threads no longer jump to the top #14808 (bump to 1.22.6, merged Oct 3), but it includes native changes and landed after 1.4.0 was cut, so your install doesn't have it.
    • Your recording doesn't quite match that, though. fix(mobile): iOS threads no longer jump to the top #14808's symptom is landing on the first message (offset 0). Your jump lands about five screens up, on the message you'd been reading earlier in the session, and you also see it while idle. That suggests a separate cause, such as the list snapping back to an earlier anchor or remembered position.
    • Not the web [Bug]: Timeline jumps far up right after sending in a long thread #13706 path either. On web, the timeline keeps maintainVisibleContentPosition on while following the end, and that jump comes from LegendList collapsing its total height when a row disappears during scrollToEnd (open PR fix(web): timeline no longer jumps up when a row is removed mid scroll #13707). The iOS feed turns that prop off while follow is armed, so sitting at the latest message shouldn't go through that path. The trigger in your recording (keyboard dismissing, composer shrinking, the Thinking row appearing) is a close cousin, though.

    Likely fix area

    Some options:

    • Check whether a build with fix(mobile): iOS threads no longer jump to the top #14808 changes anything, to rule out or isolate the keyboard-controller offset reset.
    • Look at what the iOS feed uses as a restore target or anchor (initial scroll index, a remembered offset, or a scroll-to-item target) and whether it can fire again after the user has scrolled to the end, especially on composer resize or keyboard dismissal.
    • Add logging of programmatic scroll writes in the mobile feed to catch what moves the list in the idle case.

    The recording you mentioned would help confirm which path this is.

    A maintainer will decide on the fix direction.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 4, 2026
  3. scriptease commented on Oct 4, 2026

    @scriptease

    Same on iPad, app 1.4.0. It didn't happen on the previous release.

    Another trigger alongside the idle and after-send cases: while the agent is streaming. Any incoming message can make the timeline jump away from the bottom. In a long run this happens over and over: I scroll back down and the next message throws me up again, so I can't follow the output live.

    It looks like a jump to the middle of the thread, but it may really be a jump to the top of the loaded history. Mobile only loads the latest turns and pages older ones in, so offset 0 is the top of the currently loaded batch, not the start of the thread. If so, this is the #14808 offset-0 reset rather than a separate anchor-restore cause.

  4. alhassanaraouf commented on Oct 4, 2026

    @alhassanaraouf

    Confirming this on a newer build: T3 Code iOS 2.0.0 (Build 103) via TestFlight, iPhone on iOS 27.0.1.

    Two extra triggers beyond the idle / after-send / streaming cases already reported:

    1. Scroll down by finger through a long thread; when reaching the bottom, the timeline snaps back to the top on its own.
    2. While typing a message in the composer (before sending), the timeline sometimes scrolls back to the top as well.

    Long thread with many tool calls, same as the original report. Happy to capture a screen recording if it would help isolate the anchor-restore path from the keyboard-controller offset reset.

  5. rupebac commented on Oct 4, 2026

    @rupebac

    this is making the iOS client pretty much unusable for me... it is a big pain loosing the scroll while you reading...

  6. nacholibre commented on Oct 4, 2026

    @nacholibre

    Same on iPhone, iOS app 1.4.0, server 0.0.45. Started about a day ago.

    Recording attached: in a long thread, near the bottom, I send "Hello". About 4 s later, while it shows "Working for 3s–4s" and nothing is streaming yet, the timeline jumps to the first user message of the loaded history. The scrollbar is at the top after the jump. So in my case it looks like the top of the loaded batch (offset 0), not an earlier reading position. That matches the #14808 reset theory.

    ScreenRecording_10-04-2026.21-52-19_1.mov
  7. Nelglor commented on Oct 4, 2026

    @Nelglor
    Contributor

    Note

    🤖 Claude Fable 5.1 responding on behalf of Nick

    Confirming on TestFlight 2.0.0 (105), iPhone, iOS 26, host T3 Code 0.0.46 nightly on Linux. This build was cut on Oct 4 from 4ee6bfd50, after #14808 merged, so it already ships react-native-keyboard-controller 1.22.6. The jump still happens.

    Triggers seen today in one long thread

    • Typing the first sentence of a message in the composer.
    • Dismissing the keyboard to read, then tapping the composer to bring it back.
    • Idle at the bottom while a run is in progress (the recorded case below, no touch for the previous 2 s).

    Each time it lands on the first user message of the loaded history, with the turn header flush at the top, consistent with offset 0.

    One detail I have not seen in this thread yet: the list goes blank before it repositions.

    I ran a 60 fps screen recording through a frame-by-frame scan. At the jump, the message list is completely empty for two frames (about 67 ms, only the header, the Working pill, and the composer remain), then it comes back at offset 0 with the scroll-to-end chevron shown. Nothing else in the 107 s recording blanks the list except the normal thread-open transition. A contentOffset dropped by a prop re-sort would not empty the rows, so this looks like a list remount or full re-render path, which may be why 1.22.6 alone did not close it. ThreadFeed's listMountKey flips between empty and filled when the feed momentarily holds only thinking rows; that is one candidate worth checking, though I have not confirmed it.

    Frames (30 fps strip, the blank frames are at 0.133 and 0.167):

    Ten consecutive frames: thread pinned at the bottom, two fully blank list frames, then the list at the first user message

    Clip (6 s, the reset is at about 1.1 s): https://github.com/Nelglor/t3code/releases/download/screenshots/t3-15469-reset-clip.mp4

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.via-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