Describe the bug
A useQuery with enabled: false, whose .data is read during render, stops an SSR render from
ever finishing at @tanstack/solid-query 6.0.0-rc.1. Nothing is emitted at all — the render is
stuck before any output, not stalled mid-stream.
This is the same user-visible failure as #10907, which was closed with
"experimental_prefetchInRender has been removed". That did fix the v5 path; the v6 implementation
is different, so I am filing separately rather than commenting there.
Where it comes from in rc.1. In
packages/solid-query/src/useBaseQuery.ts,
computeData() — the derive of the single createProjection that is the data node — ends:
if (state.data !== undefined) return wrap(state.data)
// Pending-idle: nothing in flight, nothing cached. …
if (isEnabled()) {
…
return chainOnce(q.fetch(opts as any), select, wrap)
}
return NEVER
with
const NEVER: Promise<never> = new Promise(noop).
So a disabled query with no cached data hands the createProjection a promise that can never
settle.
Per its docblock
(L30-L38)
that parking is intentional client behaviour: it suspends the reader into the nearest <Loading>
until the query starts fetching, "at which point the version bump re-runs the compute". On the
server there is no later — the render has to finish, and nothing will enable the query or write
the cache before it does. The three earlier return NEVER guards are each gated
(!isServer && hydrating,
!primed(),
isRestoring())
and observer.setOptions is gated !isServer, but the final disabled
return NEVER
has no isServer branch. rc.0's useBaseQuery carries several if (isServer) special-cases by
contrast.
I have not proposed a patch — what a server read of a disabled query should commit, and where the
guard belongs, looks like your call.
(Permalinks are pinned to the @tanstack/solid-query@6.0.0-rc.1 tag, commit 2222f61f9b71.)
Your minimal, reproducible example
https://github.com/TylerRick/solid-query-disabled-query-ssr-hang-repro
A git repo rather than a sandbox, because the bug only appears in a server render — it is four
files, pnpm install and one node command. Pure Solid SSR: renderToStream, one
QueryClientProvider, one useQuery. No router, no solid-start, no metaframework, no <Loading>
boundary.
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/solid-query';
const client = new QueryClient();
function Inner() {
const q = useQuery(() => ({
queryKey: ['disabled'],
queryFn: async () => 'data',
enabled: false,
}));
return <div id="out">data: {String(q.data)}</div>;
}
export default function App() {
return (
<QueryClientProvider client={client}>
<Inner />
</QueryClientProvider>
);
}
Steps to reproduce
git clone https://github.com/TylerRick/solid-query-disabled-query-ssr-hang-repro && cd solid-query-disabled-query-ssr-hang-repro
pnpm install
ENABLED=0 node render.mjs — renders the component above through @solidjs/web's
renderToStream and reports whether the stream finishes, with an 8 second cap.
- It reports
HANG — stream did not finish in 8s (bytes so far: 0).
ENABLED=1 node render.mjs — the identical code with the query enabled — reports
COMPLETED — 347 bytes.
- For the version control, set
@tanstack/solid-query to 6.0.0-rc.0 in package.json (leaving
the @tanstack/query-core override at 5.101.4), pnpm install, and repeat step 3: it
completes.
Expected behavior
A disabled query has nothing to wait for, so reading .data during SSR should expose the idle
result and allow rendering to finish. rc.0 completes with data: undefined; rc.1 also completes
when the query is enabled.
Instead the render never finishes and no bytes are produced. In a metaframework the effect is that
the page never responds at all.
How often does this bug happen?
Every time
Platform
- OS: Linux (x64)
- Node: 24.19.0
- Browser: n/a — this is a server render
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 in every row below via a direct dependency and a pnpm.overrides entry, so the
query-core bump that normally rides along with rc.1 is held constant).
TypeScript version
n/a for this bug — the reproduction's .tsx is transpiled by vite and never typechecked.
Additional context
The three-cell result, all with query-core held at 5.101.4:
| solid-query |
enabled |
result |
| 6.0.0-rc.1 |
false |
hang — stream never finishes, 0 bytes |
| 6.0.0-rc.1 |
true |
completes |
| 6.0.0-rc.0 |
false |
completes |
Full environment: solid-js / @solidjs/web 2.0.0-rc.4, @solidjs/vite-plugin 3.0.0-next.35
with @solidjs/compiler / @solidjs/babel-plugin 2.0.0-rc.4, vite 8.2.1.
Found upgrading an app to Solid 2.0.0-rc.4, where every page hung: a hook in the root chrome gates
its query with enabled on data only some routes provide, so on every other route that query is
disabled. Through TanStack Start the visible effect is that the SSR-query integration's
queryStream never closes, because router.serverSsr.onRenderFinished(...) is never reached —
but as the reproduction shows, the router is not needed and the defect is not there.
Possibly related, both closed: #10907 (the v5 original) and #8345 (<Suspense> hanging in SSR
with a disabled query).
Two PRs on the v5 line strip the never-resolving promise out of hydratableObserverResult: #10923
(closed unmerged) and #10104 (still open — its description matches this failure mode closely,
including the enabled: false case). Neither approach transfers to v6 as-is: rc.1's useBaseQuery
has no hydratableObserverResult and no createResource, and the equivalent path is the NEVER
returned from computeData into createProjection.
Describe the bug
A
useQuerywithenabled: false, whose.datais read during render, stops an SSR render fromever finishing at
@tanstack/solid-query6.0.0-rc.1. Nothing is emitted at all — the render isstuck before any output, not stalled mid-stream.
This is the same user-visible failure as #10907, which was closed with
"experimental_prefetchInRender has been removed". That did fix the v5 path; the v6 implementation
is different, so I am filing separately rather than commenting there.
Where it comes from in rc.1. In
packages/solid-query/src/useBaseQuery.ts,
computeData()— the derive of the singlecreateProjectionthat is the data node — ends:with
const NEVER: Promise<never> = new Promise(noop).So a disabled query with no cached data hands the
createProjectiona promise that can neversettle.
Per its docblock
(L30-L38)
that parking is intentional client behaviour: it suspends the reader into the nearest
<Loading>until the query starts fetching, "at which point the version bump re-runs the compute". On the
server there is no later — the render has to finish, and nothing will enable the query or write
the cache before it does. The three earlier
return NEVERguards are each gated(
!isServer && hydrating,!primed(),isRestoring())and
observer.setOptionsis gated!isServer, but the final disabledreturn NEVERhas no
isServerbranch. rc.0'suseBaseQuerycarries severalif (isServer)special-cases bycontrast.
I have not proposed a patch — what a server read of a disabled query should commit, and where the
guard belongs, looks like your call.
(Permalinks are pinned to the
@tanstack/solid-query@6.0.0-rc.1tag, commit2222f61f9b71.)Your minimal, reproducible example
https://github.com/TylerRick/solid-query-disabled-query-ssr-hang-repro
A git repo rather than a sandbox, because the bug only appears in a server render — it is four
files,
pnpm installand onenodecommand. Pure Solid SSR:renderToStream, oneQueryClientProvider, oneuseQuery. No router, no solid-start, no metaframework, no<Loading>boundary.
Steps to reproduce
git clone https://github.com/TylerRick/solid-query-disabled-query-ssr-hang-repro && cd solid-query-disabled-query-ssr-hang-repropnpm installENABLED=0 node render.mjs— renders the component above through@solidjs/web'srenderToStreamand reports whether the stream finishes, with an 8 second cap.HANG — stream did not finish in 8s (bytes so far: 0).ENABLED=1 node render.mjs— the identical code with the query enabled — reportsCOMPLETED — 347 bytes.@tanstack/solid-queryto6.0.0-rc.0inpackage.json(leavingthe
@tanstack/query-coreoverride at 5.101.4),pnpm install, and repeat step 3: itcompletes.
Expected behavior
A disabled query has nothing to wait for, so reading
.dataduring SSR should expose the idleresult and allow rendering to finish. rc.0 completes with
data: undefined; rc.1 also completeswhen the query is enabled.
Instead the render never finishes and no bytes are produced. In a metaframework the effect is that
the page never responds at all.
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 in every row below via a direct dependency and a
pnpm.overridesentry, so thequery-core bump that normally rides along with rc.1 is held constant).
TypeScript version
n/a for this bug — the reproduction's
.tsxis transpiled by vite and never typechecked.Additional context
The three-cell result, all with query-core held at 5.101.4:
enabledfalsetruefalseFull environment:
solid-js/@solidjs/web2.0.0-rc.4,@solidjs/vite-plugin3.0.0-next.35with
@solidjs/compiler/@solidjs/babel-plugin2.0.0-rc.4, vite 8.2.1.Found upgrading an app to Solid 2.0.0-rc.4, where every page hung: a hook in the root chrome gates
its query with
enabledon data only some routes provide, so on every other route that query isdisabled. Through TanStack Start the visible effect is that the SSR-query integration's
queryStreamnever closes, becauserouter.serverSsr.onRenderFinished(...)is never reached —but as the reproduction shows, the router is not needed and the defect is not there.
Possibly related, both closed: #10907 (the v5 original) and #8345 (
<Suspense>hanging in SSRwith a disabled query).
Two PRs on the v5 line strip the never-resolving promise out of
hydratableObserverResult: #10923(closed unmerged) and #10104 (still open — its description matches this failure mode closely,
including the
enabled: falsecase). Neither approach transfers to v6 as-is: rc.1'suseBaseQueryhas no
hydratableObserverResultand nocreateResource, and the equivalent path is theNEVERreturned from
computeDataintocreateProjection.