solid-query: switching the queryClient accessor strands the new client's cache (subscription stays on the old observer)
I maintainer di solito rispondono entro 1 giorno
@MaNaN1803 ci sta già lavorando.
Dal 23/7/2026.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 84/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- typescript
- Ambito
- frontend
Direzione di ricerca
Leggi packages/solid-query/src/useBaseQuery.ts nelle sezioni intorno a createClientSubscriber e client-change computed, quindi esegui packages/solid-query/src/tests/useQuery.test.tsx con il test queryClient-change. Il lavoro è completato quando la cache del nuovo client riceve il valore recuperato e l’hook esegue il rendering di quel valore dopo il passaggio da un client all’altro.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
When the queryClient accessor passed to useQuery (second argument) switches to a different QueryClient, the hook never actually moves to the new client:
- the refetch triggered by the switch lands in the previous client's cache (its
dataUpdateCountincrements), - the entry created in the new client's cache stays
status: 'pending'/fetchStatus: 'idle'forever and never receives data, - the hook keeps rendering results coming from the old observer, so the UI shows the old client's data while claiming the new client is active.
The root cause is an ordering issue in useBaseQuery. createClientSubscriber captures the observer eagerly when called (useBaseQuery.ts#L180-L181):
const createClientSubscriber = () => {
const obs = observer() // reads the signal NOW
return obs.subscribe(/* ... */)
}
but in the client-change computed it is called before setObserver(newObserver) (useBaseQuery.ts#L317-L332):
createComputed(
on(client, (c) => {
if (unsubscribe) {
unsubscribe()
}
const newObserver = new Observer(c, defaultedOptions())
unsubscribe = createClientSubscriber() // observer() still returns the OLD observer
setObserver(newObserver)
}, { defer: true }),
)
So the fresh subscription attaches to the old observer. Re-subscribing to the old (now stale) observer triggers its onSubscribe → a refetch against the old client's cache — which is where the second queryFn call comes from. The new observer ends up with zero subscribers, and a QueryObserver without subscribers never fetches, so the new client's cache entry is stranded.
Swapping the two lines (setObserver(newObserver) first, then unsubscribe = createClientSubscriber()) makes the new client's cache receive the data, with no regressions in the rest of the solid-query suite.
The existing test for this scenario (useQuery → "should refetch query when queryClient changes") passes only because it asserts toBeDefined() on the new client's cache entry — which is satisfied by the stranded pending entry. Tightening it to the exact cached value exposes the bug (see the repro branch below); this is the site I intentionally left loose in #11105.
Your minimal, reproducible example
(Alternatively, the same branch tightens the existing unit test into a failing repro: useQuery.test.tsx#L5755-L5760 — run pnpm vitest run useQuery.test.tsx -t "should refetch query when queryClient changes" in packages/solid-query.)
Steps to reproduce
- Open the StackBlitz example. The query fetches once through client 1 (both cache snapshots are rendered live).
- Click "Switch to client 2".
- Observe:
queryFnruns a second time, but client 1's cache receives the result (dataUpdateCount: 2),- client 2's cache entry stays
status=pending fetchStatus=idle data=undefinedindefinitely, - the
useQueryresult renders "result of fetch #2" — data owned by client 1 — while the active client is client 2.
Expected behavior
After the queryClient accessor switches, the query should run against the new client: its cache entry should receive the data, and the hook should be subscribed to the new observer.
How often does this bug happen?
Every time
Screenshots or Videos
State rendered by the repro after the switch:
client 1 cache: status=success fetchStatus=idle data="result of fetch #2" dataUpdateCount=2
client 2 cache: status=pending fetchStatus=idle data=undefined dataUpdateCount=0
Platform
- OS: macOS
- Browser: Chrome (also reproduced in the vitest/jsdom suite)
Tanstack Query adapter
solid-query
TanStack Query version
v5.101.4
TypeScript version
v5.9.3
Additional context
Fix ready (the reorder described above) plus the tightened assertion as a regression test. Happy to send a PR.
- Lingua principale
- TypeScript
- Stelle
- 50.4k
- Fork
- 4.2k
- Merge medio
- 7h 29m
- PR unite (30g)
- 393
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
-
solid-query: STRICT_READ_UNTRACKED on Solid 2 — client()/options() read in component body (useMutation, useBaseQuery)Forse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. 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
-
restoreQueries and persisterGc throw on malformed persisted entriesForse già presa @VGontier-cmd l’ha presa oggi. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
I maintainer di solito rispondono entro 1 giorno
-
setQueryData: NoInfer loses discriminated-union members when spreading a narrowed updater valueForse già presa @iosayin l’ha presa 2 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
I maintainer di solito rispondono entro 1 giorno
-
setQueryData updater loses discriminated-union fields when spreading inferred NoInfer dataForse già presa @boriskozak l’ha presa 2 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 68/100
TanStack/query#11794 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di TanStack/query
Issue simili
-
feat(subscription): add Manage Subscription (Stripe portal) to the Subscription tab plan cardAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
[Feature] 通知栏合并重复消息并显示次数Apertaarea:ui enhancement issue-form:feature platform:cross-platform review: high
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
1lck/Lithe-IDEA#1092 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
developmentseed/deck.gl-raster#693 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
Marker-Inc-Korea/AutoRAG#1801 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
iii-hq/iii#2278 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno