[Bug]: Mobile keeps an old model after the same thread changes on desktop
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
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
What happened
I started a thread on mobile with GPT-5.6 Sol and low reasoning. After several messages, I continued the same thread on desktop and switched to GPT-6 Astra with medium reasoning. When I returned to mobile, its composer still showed Sol. Desktop showed the newer choice.
The saved server history later shows a request for Sol again and a change back to Sol. This may affect the next message's model, rather than only its displayed label.
Steps to reproduce the reported flow
- Create a thread on mobile and select model A.
- Send messages and continue working in that thread.
- Open the same thread on desktop, select model B, and send messages using B.
- Return to mobile and start typing in the same thread.
- Check the model shown in the composer. In this case it still showed A.
- In a temporary test thread, send from mobile and inspect the requested model on the server.
Expected behavior
After a local model choice has been used and confirmed by the server, mobile should follow later model changes to the same thread. A new, unsent choice made deliberately on mobile should still be preserved.
Evidence from the affected thread
A read-only check of the local server database found these events on September 5, 2026, in UTC:
| Time | Saved event |
|---|---|
| 19:29:02 | Thread created with gpt-5.6-sol, reasoning low |
| 20:21:20 | Model changed to gpt-6-astra, reasoning medium, followed by a turn request using that selection |
| 20:24:54 and 20:26:06 | Further turn requests used Astra |
| 20:37:14 | Model changed back to Sol, reasoning low, followed by a turn request using that selection |
The later request does not identify its originating device. These records confirm the model reversal, but do not by themselves prove that mobile caused it. No thread contents or state were changed during the check.
Matching behavior in the code
At d92dca74eb7b7c6068619752f5b9a55c0e36f352, the mobile composer prefers the local draft's model over the thread's server model for both display and send. After enqueueing a message, it clears draft content without requesting model-selection removal.
The draft clear helper retains that model by default. An already-used local choice can therefore continue overriding newer server state.
A small test extracted the real draft-clear helper and used the display/send precedence expressions from the source. It seeded a local selection of A, cleared the sent message, then supplied server model B:
1.0.3-era code: mobile displays A and selects A for next send
checkout d92dca74e: mobile displays A and selects A for next send
This is a focused state-logic reproduction, not a full device or provider execution test. It assumes an existing thread-local model override; the exact path that populated this phone's override has not been captured.
Version and environment
- Native iOS app: 1.0.3, on iOS 27 as reported by the user.
- Provider: Codex.
- Desktop/server build, phone OTA runtime, and connection mode: not collected.
- The matching state behavior was tested in
3da7f9c5candd92dca74e. We should not assume the newer mobile release fixes it.
Suggested fix and verification
Treat a model choice as an unsent override until the server confirms its use, then let the composer follow the thread's saved model. Preserve a newer local choice made while an earlier send is still pending, and retain recoverable settings when sending fails.
Test the mobile-to-desktop-to-mobile handoff, the next send's requested model, a failed send, and a deliberate unsent mobile choice. Also cover an empty composer and a draft containing text.
Related work
- #6508 concerns defaults for new threads, rather than changes to the same thread on another device.
- #5421 concerns web provider-option precedence.
- #9372 updates remembered mobile options for future threads. Its stated scope does not clear an existing thread's stale draft override.
Prepared with GPT-6 in Codex from the user's observations, read-only server records, and a focused source test.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/mobile/src/state/use-thread-composer-state.ts and apps/mobile/src/state/use-composer-drafts.ts, then reproduce the focused state-logic test described in the issue. Trace how an existing local model choice affects display and the next send after draft clearing. Done means covering pending and failed sends, deliberate unsent choices, empty and populated composers, and the mobile-to-desktop-to-mobile handoff without stale model requests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100