[Bug]: Mobile 2.1.0 newly created threads become unavailable until app restart#24344

opened4d agobyBbrandon-julio-t

Creating an image thread on iOS 2.1.0 can leave it showing Thread unavailable, even though the server created it and the agent is working. Restarting the mobile app restores the conversation. This repeats the symptom in #15605 after #15870 was merged; source investigation found a later detail reader bypassing that fix's creation guard.

Area: apps/mobile. Impact: major degradation; affected conversations cannot be read until restarting the app.

Steps from the supplied incident recording:

  1. Open a new thread in an existing project.
  2. Paste an image (the T3 Code About screen in this recording), enter Testing 123, and send.
  3. Return to the thread list and open an affected newly created thread.
  4. Observe “Thread unavailable — This thread was deleted or is no longer available.”
  5. Fully quit and reopen the mobile app; the thread and response load successfully.

Expected: creation completes and the conversation remains readable without restarting. Actual: the client retains an unavailable state while the server-side thread exists. The reporter describes consistent reproduction; the underlying race is timing-dependent, and I have not reproduced it independently on a simulator.

Environment: iOS app About screen reports 2.1.0; exact iOS version and mobile build number are unknown. Remote server: Linux arm64, 0.1.3-nightly.20261024.3604. The recorded provider/model is Codex/GPT-6 Astra.

Investigation:

  • #15870 gates detail subscriptions on selectedThreadDetailRef until pending creation is delivered.
  • #20857 later added useWorkflowOpening to every mobile ThreadFeed. That hook reads the optimistic route ID directly; its parent fallback also reads that same ID for ordinary threads.
  • An initial not-found enters the shared thread state's terminal deleted state. The new reader can therefore recreate the earlier race before the existing gate permits subscription.
  • Anonymized server trace ordering for two affected creations: bounded detail request failed at +1.581 ms / +1.551 ms; successful create-command dispatch began at +36.160 ms / +4.564 ms, respectively, relative to each detail request's start. This supports early loading before creation; it does not by itself identify the calling hook.
  • A focused hook regression test on the original implementation fails: before delivery, expected no loads ([]), received ["new-thread"]. Deferring the workflow reader with the existing gate makes it pass.

Existing reports and open PRs were searched; #15605 is the closed predecessor, not an unresolved duplicate. Proposed scope is only restoring that established guard for this reader, with no new setting or workflow.

Evidence (redacted; original incident and restart workaround, not post-patch native verification): Incident recording. Composition/send excerpt followed by the unavailable frame held for two seconds; private navigation/list footage is omitted, so full navigation timing is not preserved.

https://github.com/user-attachments/assets/e3afb650-bb61-4066-9ec8-0778b1fef25b

Restart recovery excerpt. App-switcher footage is excluded.

https://github.com/user-attachments/assets/46cc46d3-1a79-4214-9b00-566d89f770ad

Thread unavailable

Recovered conversation after restart — unpatched app

Native verification limitation: Device access works, but the environment reports no devices. iOS requires macOS/Xcode; Android SDK is absent. No post-patch native success is claimed.

Investigated and prepared by GPT-6 Astra through the Codex harness in T3 Code.

Synced from GitHub

Note

Claude Opus 5.5 posting on behalf of Dmytro.

Same symptom on a physical iPhone connected remotely to a T3 Code host on macOS. Both are on the latest versions as of today, and it has happened across several app updates.

  1. Start a new thread on the phone and send the first message.
  2. The thread shows "Starting…" and nothing after it: no thinking, no reply.
  3. Go back to the thread list and reopen the thread: "Thread unavailable."
  4. Force-quit and reopen the app: the thread loads normally.

It's intermittent: a fresh attempt today did not reproduce it. It hasn't been seen with a second T3 Code host running on a server. That fits the timing race described here and in #15605. I didn't note whether an image was attached each time, and there are no server traces for these runs.

Synced from GitHub

Note

Opus (Claude Opus 5.5), Gal's assistant, posting on Gal's behalf.

Same bug here, and the same fix as #24345 resolves it on a physical device.

Setup: iPhone 14 Pro Max running a private build of the mobile app (2.1.0, built from source), connected remotely over Tailscale to a Linux x64 host running 0.1.2-nightly.20261022.3541.

Symptom: start a new thread from the phone and open it. The header shows the new title, but the body says "Thread unavailable - This thread was deleted or is no longer available." Leaving and reopening the app fixes it.

Cause: independently traced to the same place as the investigation in this issue. ThreadFeed calls useWorkflowOpening with the route thread id, so it subscribes to the thread detail while the creation is still queued. The HTTP snapshot returns not-found, the shared thread state goes to deleted, the subscription parks, and the resume cache keeps that state, so the thread stays unavailable after the creation is delivered.

Fix and verification: passing selectedThreadDetailRef into ThreadFeed and making useWorkflowOpening take a nullable ref (essentially the change in #24345). A focused test fails before and passes after; the mobile typecheck and the src/features/threads and src/state unit tests pass. Built and installed on the iPhone, newly created threads open normally without restarting the app.

Synced from GitHub

Same here, on the stable server.

  • iPhone 16 Pro, iOS 26.6.2, App Store build (current as of today)
  • Server 0.1.0 stable, Linux x64 (NixOS), behind nginx; phone on LAN or WireGuard
  • Provider: Claude

New thread from the phone: stuck on "Starting…", reopening it gives "Thread unavailable". The server log shows the thread was created and Claude answered within seconds, and the desktop app showed the reply right away. Force-quitting the app fixes it. Happened on both threads I've created from the phone so far.

Fixed on main by 59a3f52ad3 (#25477). ThreadFeed now passes the creation-gated selectedThreadDetailRef to both useWorkflowOpening and useThreadGuestShare, so neither one reads thread detail while the creation is still queued. That early read was the not-found that cached the thread as deleted.

What I ran, on main at 850d1e7a6c:

  • The regression tests from #24345 (thread-workflow-opening.test.tsx, and the ThreadFeed guest-details test in filePreview.test.ts), together with pending-thread-creation.test.ts, all pass.
  • With ThreadFeed's two readers put back to the route id (the pre-#25477 code), the ThreadFeed test fails: expected [ 'pending-thread' ] to deeply equal [].
  • The other detail readers on the thread screen (detail, structure, requests, composer state, stream haptics) all go through the same gated ref.

The App Store app gets this with the first mobile release built after #25477.

There is a second path with the same symptom: tapping a new thread's row in the thread list while its creation is still queued. That one is tracked in #25586, with a fix in #25632.