Skip to content

Mobile image thread creation stays on Starting and becomes unavailable until app restart #15603

Description

@nekohasekai

Superseded by #15605, filed using the correct Bug report template. This earlier report used the wrong template.


What happened

Creating a new thread with an image on mobile leaves the thread stuck on "Starting...", even though the server creates the thread and completes the response. Going back to the thread list and reopening it shows "Thread unavailable" / "This thread was deleted or is no longer available." Fully restarting the mobile app makes the same thread and its completed response appear.

The user reports this consistently when creating threads with images. I reproduced the complete sequence in an isolated iOS simulator with a demo image. The expected behavior is to show the created thread and stream its response without restarting the app.

Recording (22 seconds, idle waits removed; isolated demo data only):

mobile-image-thread-repro-trimmed.mp4

Diagnosis

The client loads the new thread before the server has created it. The bounded snapshot GET returned 404, then thread.create began 47.6 ms later and succeeded. The provider run completed normally; the mobile detail view remained stuck. After restarting the app, the same bounded GET returned 200.

Source at eac52f0 explains the observed sequence: use-thread-selection.ts holds selectedThreadDetailRef while creation is pending, but the composer queue-workflow subscription and ThreadDetailScreen subscriptions for reported model, queued count, and subagents use the optimistic thread ID directly. They can start the shared detail loader during attachment preparation, before startTurn/launchThread.

packages/client-runtime/src/state/threads.ts treats the initial missing/404 snapshot as a terminal deleted state and stops the subscription. Reopening the thread reuses that in-memory state; restarting clears it.

Source references: https://github.com/pingdotgg/t3code/blob/eac52f0087/apps/mobile/src/state/use-thread-selection.ts#L161 ; https://github.com/pingdotgg/t3code/blob/eac52f0087/apps/mobile/src/state/use-thread-composer-state.ts#L306 ; https://github.com/pingdotgg/t3code/blob/eac52f0087/apps/mobile/src/features/threads/ThreadDetailScreen.tsx#L309 ; https://github.com/pingdotgg/t3code/blob/eac52f0087/packages/client-runtime/src/state/threads.ts#L894

Steps to reproduce

  1. Open the iOS mobile app connected to a T3 server.
  2. Start a new task in a project using the current checkout.
  3. Add a PNG from Photo Library and enter a short prompt (for example, "Describe this demo screenshot in one sentence. Do not modify any files.").
  4. Send the task. Observe that the thread remains on "Starting..." even after the server finishes the response.
  5. Return to the thread list and reopen the new thread. It shows "Thread unavailable".
  6. Fully quit and reopen the mobile app, then open the same thread. The image and completed response now load.

The recording uses an isolated project and test image; no real conversation data is shown.

Version

Reproduced at eac52f0 (server reports 0.0.45); unmodified mobile and server checkout.

Environment

iOS 26.5 Simulator (iPhone 17 Pro); macOS 27.0.1 (26A434), Apple Silicon; local isolated dev server over loopback; Node 26.9.0; Codex 0.160.0 / GPT-6-Astra. Android not tested.

Evidence

2026-10-04 UTC; same test thread throughout:
11:06:41.380721  GET /api/orchestration/threads/<test-thread>/bounded -> 404
11:06:41.428330  thread.create begins (47.609 ms after the 404 completed)
11:06:41.442482  thread.create succeeds
11:06:41.484496  message.dispatch succeeds
11:06:48.868     provider run completed
                Mobile still shows Starting, then Thread unavailable on reopen
11:07:52.938322  After app restart: same bounded GET -> 200

Database: the thread exists and deleted_at is null.
Only two bounded GETs for this thread appear in the captured interval: the initial 404 and the 200 after restart.
Paths, credentials, and unrelated conversation content are omitted.

Related issues

#10888: older iOS deep-link hydration race, fixed in #11502; this repro uses new-task image creation. #14689: web cached-shell routing, not this mobile detail state. No matching duplicate found.

Fix applied or workaround

Fully quit and reopen the mobile app, then reopen the thread. The existing conversation and completed response load normally. No source changes were made.

Filed by

Codex harness / gpt-6-astra (ultra) in T3 Code, following the repository triage playbook.

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

    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