Describe the bug
Calling queryClient.removeQueries() while a useQuery observer is mounted removes the entry and
then immediately brings it back: the cache emits removed followed by added, the observer is
torn down and re-attached, and the recreated entry starts a fresh fetch of the key that was just
removed. At 6.0.0-rc.0 the removal sticks (entry count 0, no further events, no fetch).
The practical consequence: a caller that removes entries to make them unreadable — for example an
identity/login boundary that must guarantee the previous user's data cannot be read — cannot make
the removal last. The entry is re-created immediately, and the automatic refetch repopulates the
removed key, under whatever key and queryFn the still-mounted observer holds.
Provenance controls in the repro pin down what does and does not happen at rc.1:
- The old value is NOT retained: with the post-removal refetch parked on a never-resolving
promise, the re-added entry sits 'pending'/'fetching' and getQueryData stays undefined.
- The refetch is real: a queryFn returning
'v1' on the first call and 'v2' afterwards ends
with getQueryData === 'v2' and a fetch count of 2, with staleTime ruling out an ordinary
mount refetch.
If an active observer re-creating and refetching a removed query is intended in the rc.1 model, is
there a supported way to make removal stick — or at least be observable — while observers are
mounted?
Your minimal, reproducible example
https://github.com/TylerRick/solid-query-remove-queries-recreated-repro
A git repo rather than a sandbox because the repro is a vitest run — three files, pnpm install
and one command.
const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 60_000 } } });
const key = ['probe'];
let fetches = 0;
const queryFn = async () => (++fetches === 1 ? 'v1' : 'v2');
await queryClient.prefetchQuery({ queryKey: key, queryFn });
function Reader() {
const query = useQuery(() => ({ queryKey: key, queryFn }));
return <div>{String(query.data)}</div>;
}
// render <QueryClientProvider client={queryClient}><Reader /></QueryClientProvider>, settle
await queryClient.cancelQueries();
queryClient.removeQueries();
// settle 30ms
// rc.0: cache events […, 'removed'], 0 entries, getQueryData undefined, fetches === 1
// rc.1: […, 'removed', 'added', 'observerRemoved', 'observerAdded', 'updated', …], 1 entry,
// getQueryData 'v2', fetches === 2
Steps to reproduce
- Prefetch a key, mount one
useQuery observing it (staleTime high enough that the mount does
not refetch).
await queryClient.cancelQueries(); queryClient.removeQueries();
- Wait a tick and inspect
queryClient.getQueryCache().getAll(), getQueryData, and the fetch
count.
Expected behavior
removeQueries() leaves the cache without the entry, as at 6.0.0-rc.0 — or, if recreation by an
active observer is intended, at least does not silently refetch a key the caller just removed, and
gives the caller some way to observe/prevent the resurrection.
How often does this bug happen?
Every time
Platform
- OS: Linux (x64)
- Node: 24.19.0
- jsdom (vitest) — client-side only, no SSR
Tanstack Query adapter
solid-query
TanStack Query version
@tanstack/solid-query 6.0.0-rc.1, with @tanstack/query-core 5.101.4 (rc.1's own exact
dependency, pinned via a direct dependency and a pnpm.overrides entry, so the query-core bump
that normally rides along with rc.1 is held constant). Clean at @tanstack/solid-query 6.0.0-rc.0
with the same query-core pin.
TypeScript version
n/a — the reproduction's .tsx is transpiled by vitest/vite-plugin-solid and never typechecked.
Additional context
solid-js / @solidjs/web 2.0.0-rc.4, @solidjs/testing-library 1.0.0-beta.2, vitest 3.
Found upgrading an app from rc.0: an identity-change boundary that cancels and removes all
queries, then gates UI on the removal being observable, never sees the entries gone.
Describe the bug
Calling
queryClient.removeQueries()while auseQueryobserver is mounted removes the entry andthen immediately brings it back: the cache emits
removedfollowed byadded, the observer istorn down and re-attached, and the recreated entry starts a fresh fetch of the key that was just
removed. At 6.0.0-rc.0 the removal sticks (entry count 0, no further events, no fetch).
The practical consequence: a caller that removes entries to make them unreadable — for example an
identity/login boundary that must guarantee the previous user's data cannot be read — cannot make
the removal last. The entry is re-created immediately, and the automatic refetch repopulates the
removed key, under whatever key and queryFn the still-mounted observer holds.
Provenance controls in the repro pin down what does and does not happen at rc.1:
promise, the re-added entry sits
'pending'/'fetching'andgetQueryDatastaysundefined.'v1'on the first call and'v2'afterwards endswith
getQueryData === 'v2'and a fetch count of 2, withstaleTimeruling out an ordinarymount refetch.
If an active observer re-creating and refetching a removed query is intended in the rc.1 model, is
there a supported way to make removal stick — or at least be observable — while observers are
mounted?
Your minimal, reproducible example
https://github.com/TylerRick/solid-query-remove-queries-recreated-repro
A git repo rather than a sandbox because the repro is a vitest run — three files,
pnpm installand one command.
Steps to reproduce
useQueryobserving it (staleTime high enough that the mount doesnot refetch).
await queryClient.cancelQueries(); queryClient.removeQueries();queryClient.getQueryCache().getAll(),getQueryData, and the fetchcount.
Expected behavior
removeQueries()leaves the cache without the entry, as at 6.0.0-rc.0 — or, if recreation by anactive observer is intended, at least does not silently refetch a key the caller just removed, and
gives the caller some way to observe/prevent the resurrection.
How often does this bug happen?
Every time
Platform
Tanstack Query adapter
solid-query
TanStack Query version
@tanstack/solid-query6.0.0-rc.1, with@tanstack/query-core5.101.4 (rc.1's own exactdependency, pinned via a direct dependency and a
pnpm.overridesentry, so the query-core bumpthat normally rides along with rc.1 is held constant). Clean at
@tanstack/solid-query6.0.0-rc.0with the same query-core pin.
TypeScript version
n/a — the reproduction's
.tsxis transpiled by vitest/vite-plugin-solid and never typechecked.Additional context
solid-js / @solidjs/web 2.0.0-rc.4, @solidjs/testing-library 1.0.0-beta.2, vitest 3.
Found upgrading an app from rc.0: an identity-change boundary that cancels and removes all
queries, then gates UI on the removal being observable, never sees the entries gone.