[query-broadcast-client-experimental] broadcastQueryClient: an `added` event overwrites a receiving query that has no data (e.g. in error) with the sender's empty state
I maintainer di solito rispondono entro 1 giorno
@lazerg ci sta già lavorando.
Dal 20/10/2026.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- react, typescript
- Ambito
- backend-api-design, frontend
Direzione di ricerca
Read src/index.ts around lines 155–162 and 193–198 in the broadcast client package, then inspect the related change in #11391. The open pull request #12215 is already linked to this issue. Done means an added event no longer replaces a receiver’s settled error state with an empty pending state; the issue includes a minimal reproduction to check that behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Package: @tanstack/query-broadcast-client-experimental 5.104.3 (with @tanstack/query-core 5.104.3)
Describe the bug
When another tab creates a query, the receiving tab applies the sender's state on added whenever its own query has no data. A query that has no data but did settle (a failed query: status: 'error', errorUpdatedAt > 0) is replaced with the sender's brand-new state: status: 'pending', fetchStatus: 'idle', error: null, dataUpdatedAt: 0, errorUpdatedAt: 0.
The receiving query now looks like it is loading, but no fetch runs. Observers render a pending/loading UI indefinitely (until a refetch interval, focus or invalidation happens to trigger), and the error is lost.
src/index.ts, lines 193-198:
} else if (type === 'added') {
if (query) {
if (query.state.data === undefined) {
query.setState(state)
}
return
}
The sender posts added straight from queryCache.build, before its fetch starts (lines 155-162), so the state it carries is the initial empty state:
if (queryEvent.type === 'added') {
safePost({
type: 'added',
queryHash,
queryKey,
state,
})
}
Minimal reproduction
- Tab A and tab B both call
broadcastQueryClient({ queryClient }). - In tab A,
useQuery({ queryKey: ['x'], queryFn: () => Promise.reject(new Error('down')), retry: false }). It settles instatus: 'error', with no data. - Tab B creates the same query: either mount the same
useQuery, orqueryClient.getQueryCache().build(queryClient, { queryKey: ['x'] })(for example, as a side effect of a prefetch that has not started yet). - In tab A, the query is now
status: 'pending',fetchStatus: 'idle',error: null,errorUpdatedAt: 0. The observer shows loading, and no request is in flight.
Without the plugin, the same can be shown in a single client:
const query = queryClient.getQueryCache().find({ queryKey: ['x'] })! // in error, no data
query.setState({ status: 'pending', fetchStatus: 'idle', data: undefined, dataUpdatedAt: 0, error: null, errorUpdatedAt: 0 })
// observers now report pending with no fetch running
Expected behavior
An added event carries nothing the receiver lacks when the sender's query has never settled. The receiver should keep its own state, in particular an error.
Suggested fix
Skip an incoming added state that never received data or an error:
} else if (type === 'added') {
if (query) {
const incoming = state as QueryState
if (
query.state.data === undefined &&
(incoming.dataUpdatedAt > 0 || incoming.errorUpdatedAt > 0)
) {
query.setState(incoming)
}
return
}
A stricter variant would apply added only when it is newer than the receiver's last outcome (max(dataUpdatedAt, errorUpdatedAt)).
Workaround we use
Our query projection detects an observed query left pending with fetchStatus: 'idle' and refetches it once through its observer.
Related
Follow-up to #11391, which made added skip a receiver that already has data. A receiver without data but with an error is still overwritten.
- Lingua principale
- TypeScript
- Stelle
- 50.4k
- Fork
- 4.3k
- Merge medio
- 9h 42m
- PR unite (30g)
- 590
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/query
-
QueryClient.isFetching and useIsFetching accept a fetchStatus filter and ignore itForse già presa @Apu-Emdad l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
solid-query: STRICT_READ_UNTRACKED on Solid 2 — client()/options() read in component body (useMutation, useBaseQuery)Forse di nuovo libera @LeonxLJX l’ha presa 48 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
TanStack/query#11358 · 2 commenti · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
useBaseQuery fetches the old query key when an <Activity> tree is revealedForse già presa @lazerg l’ha presa 1 giorno fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
-
solid-query 6.0.0-rc.5: onCacheEvent throws NotReadyError during a Solid 2 (rc.14+) transition landingForse già presa @UzumakiODZ l’ha presa 7 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 28/100
TanStack/query#12031 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Explicit gcTime schedules a GC timer during SSR, retaining the whole render in memoryForse già presa @AdzerKI l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 25/100
TanStack/query#12025 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di TanStack/query
Issue simili
-
native
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
prime-radiant-inc/evener#4839 ·
I maintainer di solito rispondono entro 1 giorno
-
bug needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
processone/fluux-messenger#1790 ·
I maintainer di solito rispondono entro 1 giorno
-
🛣️ Infrastructure
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
opencrvs/opencrvs-core#14232 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
kunchenguid/gh-axi#220 ·
I maintainer di solito rispondono entro 1 giorno