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
[Bug]: Mobile thread list projection goes stale over a churning remote connection — stuck "Working", missing new threads, fixed only by app restart #5742
I included server-side traces to reproduce/investigate.
Area
apps/mobile
Summary
Over a direct Tailscale tailnet connection from a distant cellular link (no T3 Connect relay, no LAN), the mobile thread list goes stale and never reconciles: rows for threads whose provider session has already stopped keep showing Working, and a newly created thread is missing from the list — even while the WebSocket is connected, RPCs succeed, and the user is actively inside the new thread. Only a full app restart (cold re-hydration) corrects the list.
The server state is correct and current the entire time; the desktop sidebar (same server) shows the right state. This is a mobile thread-list projection/reconciliation bug, made visible by an unstable (churning) remote socket.
Steps to reproduce
Server: T3 Code desktop 0.0.32 (macOS arm64), embedded server, reached over a direct Tailscale tailnet IP (http://100.x.x.x:3773). No relay, no Tailscale Serve.
Have two threads whose provider sessions have since stopped (turns completed a while ago).
Open the app and create a new thread, send one message, get a reply.
Look at the thread list.
Expected behavior
The two stopped threads show a quiescent state (timestamp / ready / Done), not Working.
The newly created thread appears in the list.
Matches the desktop sidebar for the same server.
Actual behavior
Both stopped threads keep showing Working indefinitely.
The new thread does not appear in the list, even though it exists, is in the same project, is not deleted/archived, and the user is actively inside it.
The composer/stream inside the open thread also did not update live; the sent prompt and the reply only became visible after force-quitting and reopening the app. After that cold restart, the whole list is correct.
Server-side evidence
The backend is event-sourced (orchestration_events, monotonic sequence). Read straight from the server's state.sqlite and server.trace.ndjson at repro time (all UTC):
Authoritative server state — correct and current:
Thread
Server truth
Mobile showed
Thread A
session stopped since 20:20:40 (event seq 143721)
🔴 Working
Thread B
session stopped since 20:55:40 (event seq 143776)
🔴 Working
New thread
thread.created at 22:00:32 (event seq 143832), same project, not deleted/archived, turn completed 22:00:37
🔴 absent from list
provider_session_runtime at screenshot time: exactly 2 threads running (the active chat + the new thread's session); A and B are stopped. Latest server event: seq 143945 @ 22:05:04.
Mobile WebSocket sessions (UA okhttp), socket lifetimes:
During the healthy 140 s session the client issued many per-threadorchestration.subscribeThread calls (and vcs.*), but no thread-list-level subscription or refetch (no searchThreads, no list subscription). The new thread was created mid-session (seq 143832, 22:00:32) yet never appeared, and the two stopped rows never transitioned off Working.
Analysis (measured vs. inferred)
Measured (server): server state is correct throughout; socket connects and does unary RPC; socket churns on the distant link; per-thread subscriptions are opened, but the thread-list surface receives no live channel during a connected session.
Inferred (client, cannot measure from the server): the mobile thread list is hydrated once (cold start) and then relies on live deltas that either aren't delivered to the list surface or aren't reconciled after a reconnect gap. A full app restart forces fresh hydration and fixes it. A reconnect after a churn gap should re-fetch / replay from the last applied sequence so list-level events (thread.created, session-status transitions, thread.settled) can't be silently missed.
Relation to existing issues
[Bug]: Mobile thread list never shows Done after a turn completes #4952 ("never shows Done after a turn completes") assumes the client learns the session went quiescent but lacks a Done presentation path, falling back to timestamp. Here the row is stuck on Working and never transitions at all — the client never learns the session stopped. Complementary but a different (more severe) failure.
Server: T3 Code desktop 0.0.32 (also reproduced against a 0.0.31 self-hosted Linux server). Client: Android Play Store build as of 2026-08-08 (post-#4901). I don't have the exact mobile build hash.
Environment
Android native app, direct Tailscale tailnet IP over cellular, phone far from the server. No T3 Connect relay and no LAN Wi-Fi involved. The server is a macOS desktop 0.0.32 embedded server.
Workaround
Force-quit and reopen the app to force a cold re-hydration of the thread list.
Before submitting
Area
apps/mobile
Summary
Over a direct Tailscale tailnet connection from a distant cellular link (no T3 Connect relay, no LAN), the mobile thread list goes stale and never reconciles: rows for threads whose provider session has already stopped keep showing Working, and a newly created thread is missing from the list — even while the WebSocket is connected, RPCs succeed, and the user is actively inside the new thread. Only a full app restart (cold re-hydration) corrects the list.
The server state is correct and current the entire time; the desktop sidebar (same server) shows the right state. This is a mobile thread-list projection/reconciliation bug, made visible by an unstable (churning) remote socket.
Steps to reproduce
http://100.x.x.x:3773). No relay, no Tailscale Serve.Expected behavior
Actual behavior
Server-side evidence
The backend is event-sourced (
orchestration_events, monotonicsequence). Read straight from the server'sstate.sqliteandserver.trace.ndjsonat repro time (all UTC):Authoritative server state — correct and current:
stoppedsince 20:20:40 (event seq 143721)stoppedsince 20:55:40 (event seq 143776)thread.createdat 22:00:32 (event seq 143832), same project, not deleted/archived, turn completed 22:00:37provider_session_runtimeat screenshot time: exactly 2 threadsrunning(the active chat + the new thread's session); A and B arestopped. Latest server event: seq 143945 @ 22:05:04.Mobile WebSocket sessions (UA
okhttp), socket lifetimes:orchestration.subscribeThread, dispatchCommand, vcs.*orchestration.subscribeThread,server.probe, dispatchCommand (the new-thread send), vcs.*server.probe, vcs.*Two measured facts:
orchestration.subscribeThreadcalls (andvcs.*), but no thread-list-level subscription or refetch (nosearchThreads, no list subscription). The new thread was created mid-session (seq 143832, 22:00:32) yet never appeared, and the two stopped rows never transitioned off Working.Analysis (measured vs. inferred)
thread.created, session-status transitions,thread.settled) can't be silently missed.Relation to existing issues
Version or commit
Server: T3 Code desktop 0.0.32 (also reproduced against a 0.0.31 self-hosted Linux server). Client: Android Play Store build as of 2026-08-08 (post-#4901). I don't have the exact mobile build hash.
Environment
Android native app, direct Tailscale tailnet IP over cellular, phone far from the server. No T3 Connect relay and no LAN Wi-Fi involved. The server is a macOS desktop 0.0.32 embedded server.
Workaround
Force-quit and reopen the app to force a cold re-hydration of the thread list.