Describe the bug
Since 5.102.0 the added message carries the new query's initial state (status: 'pending', data: undefined). In every other tab the receiver does query.setState(state) when that query already exists, so a tab that has already fetched the query loses its data and goes back to pending.
In 5.101.4 the added message carried no state, and setState(undefined) was a no-op.
The change came in with #10771 (safePost refactor), where state was added to the added message along with the typed message union.
Your minimal, reproducible example
Two QueryClients in one process, wired with broadcastQueryClient over broadcast-channel's in-memory simulate transport:
import { broadcastQueryClient } from '@tanstack/query-broadcast-client-experimental'
import { QueryClient } from '@tanstack/query-core'
const wait = () => new Promise((r) => setTimeout(r, 50))
const key = ['k']
const tabA = new QueryClient()
const tabB = new QueryClient()
broadcastQueryClient({ queryClient: tabA, broadcastChannel: 'x', options: { type: 'simulate' } })
broadcastQueryClient({ queryClient: tabB, broadcastChannel: 'x', options: { type: 'simulate' } })
tabA.setQueryData(key, { data: 'value' })
tabB.getQueryCache().build(tabB, { queryKey: key }) // what a hook mounting in a new tab does
await wait()
console.log(tabA.getQueryState(key)?.status, tabA.getQueryData(key))
// 5.101.4: success { data: 'value' }
// 5.102.0+: pending undefined
Steps to reproduce
- Open the app in tab 1 and let a query resolve.
- Open tab 2, which mounts the same query.
- Tab 1's query is now
pending with no data.
Expected behavior
A tab that has already resolved a query keeps it when another tab mounts the same query. The new tab should receive the existing data (via the updated message), not the other way round.
How often does this bug happen?
Every time
Platform
- Package: @tanstack/query-broadcast-client-experimental 5.102.0 through 5.102.8 (5.101.4 is fine)
- Browser: any; also reproduces in Node with the
simulate transport
Additional context
In our app this wiped the auth-config query in every open tab, which cascaded into requests without a token and a forced sign-out of all tabs. Suggested fix: on added, do not call setState on a query that already exists in the receiving cache (or only when the local query has no data); only build it when missing.
Describe the bug
Since 5.102.0 the
addedmessage carries the new query's initial state (status: 'pending',data: undefined). In every other tab the receiver doesquery.setState(state)when that query already exists, so a tab that has already fetched the query loses its data and goes back topending.In 5.101.4 the
addedmessage carried nostate, andsetState(undefined)was a no-op.The change came in with #10771 (
safePostrefactor), wherestatewas added to theaddedmessage along with the typed message union.Your minimal, reproducible example
Two QueryClients in one process, wired with
broadcastQueryClientover broadcast-channel's in-memorysimulatetransport:Steps to reproduce
pendingwith no data.Expected behavior
A tab that has already resolved a query keeps it when another tab mounts the same query. The new tab should receive the existing data (via the
updatedmessage), not the other way round.How often does this bug happen?
Every time
Platform
simulatetransportAdditional context
In our app this wiped the auth-config query in every open tab, which cascaded into requests without a token and a forced sign-out of all tabs. Suggested fix: on
added, do not callsetStateon a query that already exists in the receiving cache (or only when the local query has no data); onlybuildit when missing.