| … | … | @@ -55,12 +56,22 @@ const EMPTY_THREAD_LINK_TITLES_ATOM = Atom.make<ReadonlyMap<string, string>>(new | |
| 70 | + | ); | |
| 71 | + | return AsyncResult.isSuccess(titles) | |
| 72 | + | ? (titles.value[ref.threadId] ?? (titles.waiting ? "Thread" : null)) | |
| 73 | + | : "Thread"; | |
🟠 High state/entities.ts:73
A pending or failed title lookup returns "Thread", which resolveThreadLink treats as proof that the candidate exists; for a v1 link whose target is loaded in another environment, this stops guessThreadLinkRef from finding it and ThreadFeed.resolveLinkedThread navigates to the wrong environment. Keep provisional display labels separate from candidate-existence results so an unconfirmed lookup cannot win.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/mobile/src/state/entities.ts around line 73: |
| 2 | |
| 3 | A pending or failed title lookup returns `"Thread"`, which `resolveThreadLink` treats as proof that the candidate exists; for a v1 link whose target is loaded in another environment, this stops `guessThreadLinkRef` from finding it and `ThreadFeed.resolveLinkedThread` navigates to the wrong environment. Keep provisional display labels separate from candidate-existence results so an unconfirmed lookup cannot win. |
Note
Generated by GPT 6.1 Sol
Confirmed and reproduced. Mobile link resolution now checks loaded shells or confirmed metadata instead of treating the provisional display label as an existence result. The regression covers pending and failed lookups, a confirmed local thread actually titled "Thread", a missing local thread, and explicitly scoped destinations. The browser navigation assertions now await the route change as well.