You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
experimental_prefetchInRender does not work with useQueryErrorResetBoundary #9978
I think there is something something missing with how errors are reset when using useQuery().promise. Which leads to the error boundary only being reset on the second try.
The problem is that you would use useQuery().promise differently from useSuspenseQuery():
With useSuspenseQuery(), you would have your <Suspense> and <ErrorBoundary> somewhere up the component tree from useSuspenseQuery:
constApp=()=>{const{ reset }=useQueryErrorResetBoundary();return(<Suspensefallback={<span>Loading...</span>}><ErrorBoundaryfallbackRender={({ resetErrorBoundary })=><buttontype="button"onClick={resetErrorBoundary}>Retry</button>}onReset={reset}><Page/></ErrorBoundary></Suspense>);}constPage=()=>{const{ data }=useSuspenseQuery(/* ... */);// do something with the data}
With useQuery().promise, you have <Suspense> and <ErrorBoundary> in the same component as useQuery():
constApp=()=><Page/>;constPage=()=>{constpromiseData=useQuery({experimental_prefetchInRender: true,/* ... */}).promise;const{ reset }=useQueryErrorResetBoundary();return(<Suspensefallback={<span>Loading...</span>}><ErrorBoundaryfallbackRender={({ resetErrorBoundary })=><buttontype="button"onClick={resetErrorBoundary}>Retry</button>}onReset={reset}><MySubComponentpromiseData={promiseData}/></ErrorBoundary></Suspense>);}constMySubComponent=({ promiseData })=>{constdata=React.use(promiseData);/* do something with the data */}
The problem is that the query will not be retried if you click the retry-button in the second example. I think the problem is that the current mechanism relys on the component that contains useQuery() (or useSuspenseQuery for that matter) to re-mount. Which of course does not happen in the second example.
Wait for the requests to finish: Both show a retry button
Click retry button in first line (useSuspenseQuery())
Click retry button in second line (useQuery().promise
Expected behavior
Both retry button should work the same: When you click them, the query is retried.
This, however, does only work for the useSuspenseQuery option. Not the useQuery().promise.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
OS: macOS
Browsers: any that I tried (Firefox, Safari, Edge)
I observed experimenting with useQuery().promise as well, and this behavior was a bit surprising. From a consumer's perspective, both patterns end up using Suspense + ErrorBoundary, so it's easy to expect the retry behavior to be consistent.
If experimental_prefetchInRender intentionally changes the lifecycle here, it might be worth documenting that useQueryErrorResetBoundary won't trigger a retry in this setup. Otherwise, having the retry behavior match useSuspenseQuery would make switching between the two APIs a lot more predictable.
@TkDodo This hook isn't quite right for me, as it has to be called inside a Suspense wrapper.
In my case, I'm using the experimental flag in useQuery, receiving and passing a promise to my Component through props or React Context, which resolves it via React.use(). And I'm wrapping my Component in Suspense. I can also use multiple consumers of this promise and define their own Suspense for each. Ex:
Activity
coderabbitai commentedon Dec 17, 2025
📝 CodeRabbit Plan Mode
Generate an implementation plan and prompts that you can use with your favorite coding agent.
Examples
🔗 Similar Issues
Possible Duplicates
Related Issues
useInfiniteQuery+experimental_prefetchInRendernever finishes loading after error boundary reset #9939useInfiniteQuery+experimental_prefetchInRenderuses error boundary for subsequent pages #9938useSuspenseQuerydoesn't throwOnError when used withrefetchInterval#8985🔗 Related PRs
#9576 - fix(core): do not reject promise right away - only when
promisegets used [merged]#9639 - fix(query-core, react-query): infinite re-renders in useQueries [merged]
#9752 - Fix unhandled promise rejections during de/rehydration of pending queries [merged]
#9772 - fix(core): observing "promise" needs to implicitly observe "data" [merged]
TanStack/router#5740 - test(solid-start-ssr-query): remove experimental_prefetchInRender [merged]
#9886 - fix: Prevent infinite render loops when useSuspenseQueries has duplicate queryKeys [merged]
👤 Suggested Assignees
🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord or schedule a call!
OliverJAsh commentedon Dec 18, 2025
I was just about the file an issue for the same thing.
experimental_prefetchInRenderexample demonstrating the issueuseSuspenseQueryexample for comparisontest(react-query): add reproduction test for useQuery().promise retry…
test(react-query): add reproduction test for useQuery().promise retry…
vaibh36 commentedon Jul 28, 2026
I observed experimenting with useQuery().promise as well, and this behavior was a bit surprising. From a consumer's perspective, both patterns end up using Suspense + ErrorBoundary, so it's easy to expect the retry behavior to be consistent.
If experimental_prefetchInRender intentionally changes the lifecycle here, it might be worth documenting that useQueryErrorResetBoundary won't trigger a retry in this setup. Otherwise, having the retry behavior match useSuspenseQuery would make switching between the two APIs a lot more predictable.
TkDodo commentedon Aug 18, 2026
this experimental flag is likely to get removed because it creates too much trouble.
vzarayskiy commentedon Aug 18, 2026
@TkDodo Is there or will there be any alternative to this experimental flag?
TkDodo commentedon Aug 18, 2026
Currently best approach is to just
useSuspenseQueryvzarayskiy commentedon Aug 19, 2026
@TkDodo This hook isn't quite right for me, as it has to be called inside a Suspense wrapper.
In my case, I'm using the experimental flag in useQuery, receiving and passing a promise to my Component through props or React Context, which resolves it via React.use(). And I'm wrapping my Component in Suspense. I can also use multiple consumers of this promise and define their own Suspense for each. Ex:
Is there an alternative that would allow me to maintain my approach and structure?
TkDodo commentedon Aug 19, 2026
replace
useQuerywithusePrefetchQueryand calluseSuspenseQueryin the child componentsvzarayskiy commentedon Aug 19, 2026
@TkDodo thank you