Skip to content

Mobile (Android): Chats list doesn't show threads created elsewhere until you navigate #842

Closed

Description

@Jacksondr5

Posted by an AI agent (Claude Opus 5.5) on Jackson's behalf.

What happens

On Android (J5 Code Dev, Android 16, trunk 31447c91c6), the Chats list stays stale while it's open. Threads created on web don't appear, even after they've started and finished turns:

  • After a cold pairing, the list finishes "Syncing threads" but shows only the threads that existed before. A Haiku sender thread created on web, and the peer agent it spawned, are both missing.
  • Opening any existing thread and pressing Back brings the new threads into the list. No reload is needed.
  • A later thread created on web goes missing the same way while the list stays open. Re-running the rig's mobile-open also brings it in.

Repro steps, evidence and limits are in the project artifact test-reports/j5code-mobile-wave1b-tester/31447c91c6.md. Found during the mobile live round as candidate L-a2a-1 and confirmed by the wave-1 tester.

Open questions

  • Zone. Is this upstream's thread-list subscription, or something J5 changes (people and access narrowing, multi-environment merge)? Check whether upstream's mobile app on an upstream server behaves the same before fixing it in J5. If it's upstream's, it goes to the give-back list.
  • iOS hasn't been checked yet.

Done when

A thread created on another client appears in the open mobile Chats list without navigating, on Android and iOS.

Activity

  1. added this to the Mobile catch-up milestone on Nov 1, 2026
  2. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Second, independent reproduction (2026-10-31, builder-archive-artifacts, Android emulator). It isn't limited to a cold start, and it can drop only some of the new threads.

    The app was paired with mobile-open at 20:12. Then, within about 30 s on web:

    • Thread A (Haiku) opened an ask and spawned child A′.
    • Thread B did the same, spawning child B′.
    • Thread C was a plain reply.

    On Android, A, C and one child appeared within a minute. B and the other child were still missing about 3 minutes later, while web listed all five. An app reload (mobile-open) brought B back.

    So some thread-list updates are lost while the list is open. That points at the list subscription or merge rather than the initial sync. — Claude Opus 5.5 for Jackson

  3. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Debug run, 2026-10-31 (wave-1a tester, Android, j5/main code plus HOME842 logs; head 3d5d8546b0 on j5code/mobile-edit-task-debug). Code read by builder-composer. Nothing is fixed yet.

    Reproduced with Home visible. After a cold pair, a thread created on web ("Untouched Chats Observation") stayed missing from Chats for more than 60 seconds with the device untouched. Opening another thread and pressing Back brought it in.

    What the logs rule out

    • Home's visibility gate (useHomeRouteVisible / useAtomValueWhileVisible, upstream fix(mobile): pause hidden home thread list updates pingdotgg/t3code#15705), which was the first suspect. visible was true throughout, and shown equalled live (21 = 21). So HomeRouteScreen held every thread, including the missing one, in its threads prop.
    • The shell stream and reducer (client-runtime/state/shell.ts, shellReducer.ts): the thread reached navigationThreadShellsAtom.
    • J5's people-and-access narrowing: it applies only to narrowed (guest) connections, and the rig pairs as the owner.

    What the code rules out

    • buildThreadListV2Items (features/threads/threadListV2.ts) puts every listed thread into a shelf. No time or count cutoff drops a new active thread.
    • The held thread order (state/thread-order.ts) only starts when someone reorders threads (useThreadListActions), and nobody did in the repro.

    Remaining suspect: the virtualized list. Chats is an AnimatedLegendList (features/home/HomeScreen.tsx) with recycleItems, itemsAreEqual, and an extraData object that, per its comment, "invalidates every visible row". Opening a thread changes selectedThreadKey, which is in extraData. That fits the one action that brings the thread in, but isn't confirmed. The next check would log threadListV2Items keys against the rows Legend List renders.

    Separately, upstream: HomeScreen's minute clock is set in a useFocusEffect without useCallback. That re-arms its 60-second interval on every render, so now can stall while threads stream. It's not the cause here, but worth noting.

    Zone: upstream (HomeScreen.tsx, @legendapp/list), with no J5 code on the path. Upstream's own app would behave the same if Legend List is the cause. Candidate for the give-back list once confirmed.

    — Posted by an AI agent (Claude Opus 5.5) on Jackson's behalf.

  4. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Second debug run (wave-1b tester, Android, c48ef2a944 on j5code/mobile-842-list-debug: logs the item keys handed to the Chats list and each row's first render, with switchable list variants). This corrects my previous comment: Legend List is cleared.

    What the run showed (raw log on the tester's host, /tmp/wave1b-list842/metro-full.log):

    • Base, after a cold start: a thread created on web never entered the list's items while the device sat untouched for over 2 minutes. The only change, when the web thread started, was a new v2-working-shelf item (the Working section's header). The thread's own row entered the items only after opening another thread and pressing Back, and Legend List drew it at once. So no row was lost between the items and the screen.
    • Every later web thread in the same session, created after that first navigation, moved from the Working section into the list within 60 s untouched. That held with recycleItems={false} and with a bumped extraData, so those variants show nothing.

    Reading: the new thread is filed in the Working section while its turn runs, as designed (upstream's beta section, pingdotgg#15346). buildThreadListV2Items puts that section's header after every active thread, so with 27 threads it sits below the viewport, which fits the tester's top-of-list screenshots showing no header. After the turn, the thread should return to the main list after a 2 s grace period (createInboxReturnTracker, client-runtime state/threadInbox.ts). For the first new thread after a cold start, that return never happened until navigation.

    Open question, unconfirmed: why the first return doesn't fire. Candidates:

    • the tracker's grace timer or its version signal not re-rendering HomeScreen;
    • isThreadWorking still classifying the thread as working. A runtime idle status doesn't exit early there.

    A targeted log would settle it: per render, the new thread's isThreadWorking, its runtime and latest-run status, the tracker's view, and the inbox version. Plus a screenshot scrolled to the Working section.

    Zone: all upstream (the client-runtime inbox tracker, the mobile Working section), with no J5 code on the path. Candidate for the give-back list once confirmed.

    — Posted by an AI agent (Claude Opus 5.5) on Jackson's behalf.

  5. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Summary: intermittent; parked for Checkpoint 1. There were three debug runs on Android.

    • Two reproduced it. Once right after a cold pair: one of two new threads stayed missing while the list was open. Once after a cold start: the first new thread was missing for 2+ minutes.
    • One run was clean: a fresh cold start, with the thread back within 60 s.
    • In both reproductions, the thread appeared after opening another thread and pressing Back.
    • Ruled out: Home's visibility gate, the shell stream, J5's access narrowing, the held thread order, and the list component (Legend List).
    • Remaining suspects: the Working section's release of a finished thread (client-runtime createInboxReturnTracker, scheduled from render), or a run status that stays "working". Both are upstream's. Reopen if Jackson hits it.

    Third debug run: not reproduced; parked (wave-1b tester, Android, fresh cold start; head e5438de8b7 on j5code/mobile-842-working-debug, which logs each thread's working classification and the Working section's grace timer). Raw log on the tester's host: /tmp/wave1b-work842/metro-full.log.

    What happened: the first web thread after a cold start took the intended path, and it showed in Chats within 60 s:

    • While the turn ran, both isThreadWorking and the inbox tracker reported it working: preparing → starting → running → waiting.
    • Once the run completed, the tracker held it for the 2 s grace (schedule 2000 ms, listeners = 1), then fired (fired listeners = 1). inboxVersion went 0 → 1, and the thread left Working.

    So the mechanism works, and the earlier failures need a condition this run didn't hit.

    What a reproduction must show. Keep e5438de8b7 for the next attempt. When a thread sticks, its logs answer these:

    1. Does the stuck thread still read isThreadWorking = true after its run completes, for example a run left in waiting? That would point at the shell's runtime or run status, not the client.
    2. Or does it read [false, true, …], with the tracker holding it? Then look at whether tracker fired logged, and with how many listeners. If the timer fired with listeners = 0, or never fired, the release only lands at the next render of Chats, and on a quiet server that next render is the navigation. That matches every failure seen so far.

    The tracker schedules its timer from inside render (observe runs in useThreadListV2's useMemo). The release depends on a later re-render reading the bumped version. That's the most likely place for the fix, and it's upstream's (client-runtime state/threadInbox.ts, mobile useThreadListV2.ts). No J5 seam is warranted before that's confirmed. Parked for Checkpoint 1; give-back candidate once reproduced.

    — Posted by an AI agent (Claude Opus 5.5) on Jackson's behalf.

  6. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Reproduced on iOS at Checkpoint 1 (2026-11-01, Jackson's iPhone, trunk e3b06c5747). A Haiku thread started from web ("Checkpoint 842 Watch", 12:01:26 to 12:01:39 EST) appeared under Working in Chats and stayed there after its turn ended, with Chats left open. It's no longer parked: this matches the inbox-return theory, where the thread doesn't leave Working until something re-renders Chats. — Claude Opus 5.5 for Jackson

  7. Jacksondr5 commented on Nov 1, 2026

    @Jacksondr5
    OwnerAuthor

    Decided (Jackson, 2026-11-01): fix it in J5 with a small, recorded seam, and hand it to the give-back agent for upstream (#276). The cause is in upstream's shared thread-list and inbox-return code. — Claude Opus 5.5 for Jackson

  8. added a commit that references this issue on Nov 2, 2026
    7fc0f2b
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

    No labels
    No labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions