B was selected. A stayed visible.
See the mounted component path, the missing request, and the manual reload control.
Follow the switch →An app switched its assistant from workspace A to B while the AI SDK component stayed mounted. The Cloud adapter changed, but the visible conversation list did not. A’s conversations remained on screen until the list was explicitly reloaded. We reproduced that handoff, tested a local repair, and followed the fix through merged upstream PR #8955.
On the pinned upstream source, the focused baseline recorded 10 expected failures and 15 passes. After the local repair, the four-file run passed 28/28; an exact-input replay also passed 28/28. The public PR’s later verification is reported separately below.
See the mounted component path, the missing request, and the manual reload control.
Follow the switch →Compare upstream, explicit reload, repaired behavior, and nine follow-up variations.
See the controls →Preserve selection and ownership while replacing the visible list.
Read the repair →PR #8955 carries the final fix, expanded controlled-selection coverage, and upstream checks.
View merged PR #8955 →A workspace selector is only correct if the list below it follows the newly selected Cloud client and scope. The mounted AI SDK wrapper changed its adapter without telling the retained list runtime to replace its visible state.
workspace-a shows a-thread.scopeId changes without unmounting.b-thread appears.The app passes a Cloud client and scopeId to AISDKThreads. That wrapper constructs a Cloud thread-list adapter for RemoteThreadList. The list runtime holds the last visible records until threads.reload(). At the investigated revision, replacing the wrapper’s adapter did not call that lifecycle operation.
The source-pinned AI SDK wrapper and remote-list reload contract show the handoff. The pin is revision 5e64867 of @assistant-ui/ai-sdk 0.0.11; the baseline observation belongs to that revision.
A stale client-visible list after a workspace change. The local test did not exercise hosted Assistant Cloud authorization or establish a server-side cross-account read.
The controls measure visible threads, list calls, history requests, message writes, and run cancellation. Each answers a different part of the claim.
Investigate the exact upstream wrapper and remote-list implementation at revision 5e64867.
Render AISDKThreads on A, switch to B, and read the visible list and actual client calls.
On the same upstream component, call the public list reload and check whether B replaces A.
Repeat client and scope changes, delayed responses, active runs, shared IDs, and new writes.
Without a reload, A remained and no B list request appeared. A manual threads.reload() requested B and removed A. The local wrapper repair performed that same operation after the new adapter was committed.
The A/B fixture held the mounted component and workspace transition constant. The explicit-reload case isolates the missing step.
| Observation | Pinned upstream | Local repair |
|---|---|---|
| Initial load on A | a-thread visible | a-thread visible |
| Switch to B while mounted | A remains visible; no B list request | B requested; A removed; b-thread visible |
| Manual reload on upstream | B loads and A disappears | Wrapper schedules the equivalent reload |
| Active A run during switch | Failed B transition blocks later assertions | A run stops once; no A message written to B |
| New message after B | Failed B transition blocks this branch | B receives the write; A receives none |
The baseline’s failed B transition prevents its downstream cancellation and write assertions from running to completion. Those assertions are observations from the repaired variations.
Eight cases used controlled in-memory Cloud clients. One used the real AssistantCloud SDK against a controlled local HTTP A/B service. All exercised the mounted AI SDK component path.
| Changed condition | Repaired observation | What it checks |
|---|---|---|
Same client, new scopeId | B replaces A; unchanged rerender does not reload | Scope alone is enough, without an ordinary-render loop |
| New client and scope, then back to A | B loads; the return loads A | Both directions work |
| New client, same scope | Replacement client receives the list request | Client identity also triggers the handoff |
| Late A list response | B remains the visible list | Old requests cannot restore A |
| Active A run; same remote thread ID in A and B | B record wins; A run stops once; zero A writes land in B | ID reuse does not carry the old run into B in the fixture |
| Rapid A → B → C | C is the settled list | Superseded reloads do not leave B visible |
| New conversation after B | B receives the new write; A receives none | Fresh work follows the selected client |
| Late A history response | B’s saved message remains; A’s stays out | Old history does not overwrite B |
| Real Cloud SDK, local HTTP A/B fixture | B list and history GETs carry B owner/workspace headers | Client request routing in a controlled service |
Controlled clients count writes and cancellations. The HTTP fixture records list and history requests through the real SDK against local responses. Neither replaces a hosted service authorization test.
When the Cloud client or scope changes, the AI SDK wrapper waits for React to commit the replacement adapter, then calls threads.reload(). Superseded scheduled work is canceled.
The local patch changed the wrapper, added a focused regression, and supplied a patch changeset. Upstream review expanded the final behavior to preserve controlled thread selection during the same transition.
The wrapper reloads after the new adapter commits. The old list disappears, the B list arrives, and the reattack variations pass on the pinned source.
The final change also handles a controlled threadId changed in the same render, avoids a duplicate initial Cloud load, and protects later selections and failed-load recovery.
reload(). The AI SDK wrapper knows when the Cloud client or scope genuinely changes.main on October 8, 2026.The workspace-scope issue #7203 and merged PR #7275 explain the earlier Cloud scope boundary. Merged PR #6080 defines list reset and explicit reload after an adapter replacement. PR #8955 connects that contract to the AI SDK wrapper’s actual workspace transition.
The local report measured the pinned wrapper and its focused repair. The merged PR’s public description records additional fixes and its own suite results.
| Evidence set | Result | Where it applies |
|---|---|---|
| Pinned baseline | 10 expected failures, 15 passes | Three focused files on upstream 5e64867 |
| Local repair and replay | 28/28, then 28/28 | Four focused files on repaired pinned checkout |
| Wider local compatibility | AI SDK 473/473; core 3,082/3,082; Cloud 289/289 on each v7 and v6 peer | Research checkout; separate from the focused replay |
| Merged PR verification | AI SDK 478 tests; core 3,377 tests; builds, typechecks, focused formatting and lint checks passed | PR #8955 verification record, with expanded controlled-selection tests |
The pinned report also records 445 passing React 18 peer tests with 28 suite-design skips, React compiler 1/1, and standalone AI SDK 3/3. Counts from the later merged PR are intentionally kept separate.
The research report describes an offline Linux x64 reviewer kit that runs the expected baseline failure, repair, and exact replay. That archive is not hosted by this page. The linked upstream PR, source pin, and test record are the public evidence readers can inspect here.
The failure was a missing client lifecycle step. The repair makes the selected workspace and visible list move together, including under delayed responses and interrupted work in the controlled fixtures.
Changing the adapter is not enough when the list keeps its previous records. The wrapper must explicitly reload after the replacement is committed, while the list runtime rejects work left behind by the old adapter.
The result here is a repeatable stale conversation list on the pinned client and a merged upstream correction. The controlled HTTP fixture does not prove that a hosted service returned an unauthorized conversation or accepted an unauthorized message.
Start with the merged fix, then inspect the related scope and reload work or the exact source revision used for the baseline.
We trace the selected owner, the runtime state, and the actual requests or effects, then work with maintainers to make the boundary hold.
48-hour Rapid Scan →