Skip to content

invalidateQueries inconsistently cancels fetchQuery #8060

Description

@SebKranz

Describe the bug

fetchQuery may throw an CancelledError { silent: true, revalidate: undefined } under the following conditions:

  • the query is stale (otherwise the fetch won't run).
  • the query is invalidated at least one tick after the fetch started.
  • the query is in an active state. For example because a component with useQuery is still mounted.

In the real world, this might happen in combination with react-router, when the user submits a form and then navigates to a new (or the same) page. In my case, we were updating a search param to close a modal after a form submission, which then triggered the loader function containing a fetchQuery call. We're also using a mutation observer1 to trigger invalidations, which is why the invalidation happened only after the navigation began.

I fixed the issue by using ensureQueryData instead of fetchQuery. This is the better choice anyways.

Still, this seems like a footgun since it is difficult to catch while testing. Further, if the intended behavior for fetchQuery is to throw a CancelledError on invalidation, it should always do that and not only when a revalidation is triggered.

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/react-query-cancellederror-on-invalidation-d4g259

Steps to reproduce

See steps above

Expected behavior

Option A: The returned promise should consistently reject, regardless of whether an unrelated observer exists.
Option B: The returned promise should consistently resolve with the data returned from this fetch
Option C: The QueryClient should treat pending promises as observers, revalidate automatically and always resolve with the result from the latest revalidation.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Tanstack Query adapter

react-query

TanStack Query version

5.50.1

TypeScript version

No response

Additional context

No response

Footnotes

  1. inspired by https://tkdodo.eu/blog/automatic-query-invalidation-after-mutations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions