Describe the bug
A useQuery with enabled: false never settles its underlying createResource during SSR, so renderToStringAsync (and SolidStart's async/stream SSR) hangs as soon as the disabled query's .data is read during render.
On the server, solid-query forces experimental_prefetchInRender = true (useBaseQuery), so the observer result carries a .promise. For a disabled query that promise never resolves, and the resource fetcher returns it (via hydratableObserverResult) instead of short-circuiting — so the SSR render awaits a promise that can never settle.
Reproduces on @tanstack/solid-query@5.101.0 (latest) with solid-js@1.9.13.
Related, both closed and neither matching this exact symptom (single useQuery, SSR render hang): #6256, #7167.
Your minimal, reproducible example
Standalone Node ESM — no framework needed. solid-js/web resolves to its server build under Node's default node export condition, so isServer === true.
// repro.mjs -> node repro.mjsimport{renderToStringAsync,createComponent,Suspense}from'solid-js/web'import{QueryClient,QueryClientProvider,useQuery}from'@tanstack/solid-query'constclient=newQueryClient()functionInner(){constq=useQuery(()=>({queryKey: ['disabled'],queryFn: ()=>Promise.resolve('data'),// never runs (disabled)enabled: false,}))return()=>`data=${JSON.stringify(q.data)}`// reading data drives the resource}constApp=()=>createComponent(QueryClientProvider,{
client,getchildren(){returncreateComponent(Suspense,{getchildren(){returncreateComponent(Inner,{})},})},})// The race timeout is ONLY so the script exits; renderToStringAsync never settles.consthtml=awaitPromise.race([renderToStringAsync(()=>createComponent(App,{})),newPromise((_,r)=>setTimeout(()=>r(newError('renderToStringAsync did not settle (5s)')),5000),),])console.log(html)Steps to reproduce
npm i @tanstack/solid-query@5.101.0 solid-js@1.9.13node repro.mjs- Observe it never resolves — the 5s race rejects with
renderToStringAsync did not settle.
Expected behavior
A disabled query must not suspend SSR; the resource should resolve immediately with the idle state.
Possible fix
Short-circuiting enabled === false in the useBaseQuery resource fetcher — returning the synchronous result with the dangling .promise stripped — fixes it. Verified locally against 5.101.0:
// inside the createResource fetcher, before `return new Promise(...)`constobs=observer()if(obs.options.enabled===false){const{ promise, ...rest}=hydratableObserverResult(obs.getCurrentQuery(),observerResult)returnrest}- unpatched: hangs (5s timeout above)
- with the short-circuit: resolves in ~25ms with the correct idle state
Happy to open a PR if this approach looks right — wanted to confirm the direction first, since it touches the core query path and enabled can also be reactive (this handles the literal false case).
Environment
@tanstack/solid-query@5.101.0, solid-js@1.9.13, Node 24.
Describe the bug
A
useQuerywithenabled: falsenever settles its underlyingcreateResourceduring SSR, sorenderToStringAsync(and SolidStart's async/stream SSR) hangs as soon as the disabled query's.datais read during render.On the server, solid-query forces
experimental_prefetchInRender = true(useBaseQuery), so the observer result carries a.promise. For a disabled query that promise never resolves, and the resource fetcher returns it (viahydratableObserverResult) instead of short-circuiting — so the SSR render awaits a promise that can never settle.Reproduces on
@tanstack/solid-query@5.101.0(latest) withsolid-js@1.9.13.Related, both closed and neither matching this exact symptom (single
useQuery, SSR render hang): #6256, #7167.Your minimal, reproducible example
Standalone Node ESM — no framework needed.
solid-js/webresolves to its server build under Node's defaultnodeexport condition, soisServer === true.Steps to reproduce
npm i @tanstack/solid-query@5.101.0 solid-js@1.9.13node repro.mjsrenderToStringAsync did not settle.Expected behavior
A disabled query must not suspend SSR; the resource should resolve immediately with the idle state.
Possible fix
Short-circuiting
enabled === falsein theuseBaseQueryresource fetcher — returning the synchronous result with the dangling.promisestripped — fixes it. Verified locally against 5.101.0:Happy to open a PR if this approach looks right — wanted to confirm the direction first, since it touches the core query path and
enabledcan also be reactive (this handles the literalfalsecase).Environment
@tanstack/solid-query@5.101.0,solid-js@1.9.13, Node 24.