-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
Describe the bug
So i have a useQuery setup to fetch a cart i want that if the server fetches the cart with an 401 error that the query with the error should not be retried and is then included by conditionally setting shouldDehydrateQuery true like described in the docs so my code for retrying is
retry: (failureCount, error) => {
return shouldRetry(error.status) && failureCount < 3;
},
My code in the server side loader
const dehydratedState = dehydrate(queryClient, {
shouldDehydrateQuery: (query) => {
if (query.state.error && query.state.error.status) {
// Invert the shouldRetry logic to determine if we should dehydrate the query
// so if we should not retry the query, we dehydrate it so the query is not retried
// If you for some reason want to include failed queries in the dehydrated state to avoid retries, you can use the option shouldDehydrateQuery to override the default function and implement your own logic.
return !shouldRetry(query.state.error.status);
}
return typeof window === "undefined" && defaultShouldDehydrateQuery(query);
},
});
dehydratedState.queries.forEach((query) => {
if (query.state.error instanceof ApplicationError) {
query.state.error = serializeApplicationError(query.state.error);
}
if (query.state.fetchFailureReason instanceof ApplicationError) {
query.state.fetchFailureReason = serializeApplicationError(query.state.fetchFailureReason);
}
});
return {
categories,
dehydratedState,
};
And in the client every dehydrated query is the deserialized
if (query.state.error) {
query.state.error = deserializeApplicationError(query.state.error);
}
if (query.state.fetchFailureReason) {
query.state.fetchFailureReason = deserializeApplicationError(query.state.fetchFailureReason);
}
And i can also see that the first log of the dehydrated state directly has correct and real error class with the error.status populated however it still is going to fetch one time directly after mount but the dehydrated state has the correct error status to normally set retry: false but it still retries i think that the query doesnt see in time or check that error from the dehydrated state before its going to retry.
Your minimal, reproducible example
Steps to reproduce
- Create a SSR Setup with React Query
- Dehydrate a errored query with some property that can be dynamically checked e.g status
- Make the query retry to a custom function that returns false if that condition is met e.g error.status = 401
- And see it is still going to retry rather then just not doing that like described in the docs
Expected behavior
// If you for some reason want to include failed queries in the dehydrated state to avoid retries, you can use the option shouldDehydrateQuery to override the default function and implement your own logic
// limitations
Some storage systems (such as browser Web Storage API) require values to be JSON serializable. If you need to dehydrate values that are not automatically serializable to JSON (like Error or undefined), you have to serialize them for yourself. Since only successful queries are included per default, to also include Errors, you have to provide shouldDehydrateQuery, e.g.:
tsx
// server
const state = dehydrate(client, { shouldDehydrateQuery: () => true }) // to also include Errors
const serializedState = mySerialize(state) // transform Error instances to objects
// client
const state = myDeserialize(serializedState) // transform objects back to Error instances
hydrate(client, state)
Both things are handled correctly and its a little bit annoying of that additional fetch on mount, after the first double fetch it however stops because then the retry sees the custom error.status and stops fetching but that would also work if i just dont dehydrate the query at all, so to not avoid retries, but in this case i need to avoid retries
I have some routes that have critical data where this doesnt matter at all because i just early throw and not retry at all but here i dont throw and i also dont just want to blindly retry, and if im trying to do a custom retry function it still fetches one time thats annoying
How often does this bug happen?
Every time
Screenshots or Videos

Platform
- OS: Windows
- Browser: Firefox
Tanstack Query adapter
react-query
TanStack Query version
5.83.0
TypeScript version
5.8.3
Additional context
No response