Repository navigation
solid-query 6.0.0-rc.1: a tracked read through createMemo(() => query.data) re-runs on refetch but reads the previous value, and is never notified again #11351
Description
Describe the bug
A tracked computation that reads query data THROUGH a createMemo(() => query.data) indirection
re-runs after a refetch — but reads the value from before the refetch, and is never notified
again, so its last observation stays stale permanently. At 6.0.0-rc.0 the same computation reads
the new value.
Narrowing, all measured at rc.1:
- An effect reading
query.datadirectly (no memo) observes the new value — the memo indirection
is the trigger. - The same value change committed synchronously via
queryClient.setQueryData()is observed
through the memo too — the failure needs the refetch path, where the data projection's derive
returns a promise and the commit is asynchronous. - The memo itself never recomputes across the refetch (consistent with the data node being one
stable store root reconciled in place), and after everything settles the memo's cached value is
===a directquery.dataread — at which point an UNTRACKED read through the memo returns the
NEW value. So the stale read happens at notify time: the effect re-runs before the new value is
observable through the memo, and no second notification arrives after it commits. - Two pure-solid
createProjectionmimics of the rc.1 data-node shape (a promise-returning
derive, a memo over the root leaf, an effect reading through the memo — with and without the
derive reading its own previous committed value) both pass on solid-js 2.0.0-rc.4, so this does
not look like a generic solid-js memo-over-projection defect, at least not in the documented
shape.
A memo over query.data is the natural shape of any wrapper hook that gates or narrows a query's
data before handing it to consumers, so this bites app code that never spells
createMemo(() => query.data) explicitly.
Your minimal, reproducible example
https://github.com/TylerRick/solid-query-stale-read-through-memo-repro
A git repo rather than a sandbox because the repro is a vitest run — four files, pnpm install
and one command.
function Probe() {
const query = useQuery(() => ({
queryKey: key,
queryFn: async () => ({ ...serverValue }),
}));
const data = createMemo(() => query.data);
createEffect(
() => data()?.video1,
(video1) => {
captured = video1;
},
);
return <div />;
}
// serverValue starts { video1: false }; after mount+settle:
// serverValue = { video1: true }; await queryClient.refetchQueries({ queryKey: key }); settle
// rc.0: effect re-runs, captured === true
// rc.1: effect re-runs, captured === false — and no further notification ever arrivesSteps to reproduce
- Mount a
useQuery, read one of its data properties in a tracked computation THROUGH a
createMemo(() => query.data). - Let the first fetch settle, then
refetchQuerieswith the queryFn now returning a fresh object
with a changed value. - The tracked computation re-runs but captures the previous value, and never re-runs again.
Expected behavior
The re-run observes the new value (as at 6.0.0-rc.0), or a second notification follows the commit.
Either way a subscriber's LAST observation should not be the superseded value.
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: its wrapper hook returns a gate memo over query.data, so every
fine-grained subscriber downstream of the hook captured pre-refetch data forever after any
refetch. Reduced by subtracting from the failing app test — reconcile: 'id', deep(), the
nested data shape, cache priming, staleTime, and enabled were each removed with the failure
persisting.
Possibly related context: rc.1's rewrite of useBaseQuery onto Solid 2's native async model
(#11308), which replaced the resource machinery with a single createProjection data node.
Activity
Backlink to the filed issue, TanStack/query#11351
mgarcialeniolabs commentedon Sep 1, 2026
I'll work on this.
TylerRick commentedon Sep 3, 2026
Update from the reporter: Thanks for filing that on the solid side. This no longer reproduces once solid-js / @solidjs/web are at
2.0.0-rc.6 — measured 2026-09-03 against the linked repro at both
@tanstack/solid-query6.0.0-rc.1 and 6.0.0-rc.2 (query-core 5.101.4): all 6 tests pass, and the effect re-runs after the refetch and reads the new value through the memo.Holding solid-query rc.1 constant while changing Solid from rc.4 to rc.6 is what isolated the change, so the fix appears to have landed on the Solid side in the rc.4 → rc.6 range. Because solid-query rc.2 requires
solid-js >=2.0.0-rc.6, the bug should not occur in a supported rc.2 installation. Sharing this before work continues; a regression test may still be worthwhile.