-
-
Couldn't load subscription status.
- Fork 3.5k
Description
Describe the bug
Hello!
It appears that isFetchedAfterMount was broken in 5.87.1 through that change inadvertently updating the dataUpdateCount. We're seeing behavior where the isLoading flag is set to false when data is loaded from cache, but since isFetchedAfterMount is inadvertently set to true too early we can't tell if that data was loaded from the server or from the cache. In essence, I believe that in cases where you are persisting data the isFetchedAfterMount flag might be entirely broken.
From Claude's analysis:
Root Cause Analysis
The commit 1c8a92167769f322d0206325b98493769afb0961 introduced logic that updates initialData when a Query exists without data. The issue is that when setData is called with manual: true, it increments dataUpdateCount from 0 to 1, even though this data wasn't actually fetched from the server but just set as initial data.
The Problem Flow:
- Prefetch scenario: A query is created via prefetching (data is undefined, status is pending)
- Observer mounts with initialData: When an observer mounts with
initialDataset - setOptions is called: The new code in
query.ts:210-218detects the query has no data and sets the initialData - setData with manual:true: This calls
setDatawithmanual: true, which incrementsdataUpdateCountfrom 0 to 1 - queryInitialState capture: The observer captures the query state as
#currentQueryInitialStatewithdataUpdateCount: 1 - isFetchedAfterMount calculation: When calculated, it compares current
dataUpdateCount(1) with initialdataUpdateCount(1), resulting in false initially, but any subsequent update makes it true prematurely
Your minimal, reproducible example
https://codesandbox.io/p/github/0xdiid/simple-is-fetched-repro/main?import=true
Steps to reproduce
Steps are in the repro app itself, but a quick copypaste here:
- Click "1. Prefetch Query" - Creates query with undefined data, but starts fetching with a 3 second delay
- Click "2. Mount Observer with initialData" - Triggers the bug (if pressed before 3 seconds)
- If you clicked 2 before 3 seconds, you should see isFetchedAfterMount be true which is not expected
- You can now click "3. Reset" to reset the state and wait for 3 seconds after clicking 1 to see flags set "properly"
Expected behavior
As a user, I expect isFetchedAfterMount to only trigger when the data is fetched from outside of the persisted cache, which matches previous implementations
How often does this bug happen?
Every time
Screenshots or Videos
Screen.Recording.2025-09-15.at.9.45.47.PM.mov
Platform
- OS: mac
- Browser: chrome
- Version: 140.0
Tanstack Query adapter
react-query
TanStack Query version
v5.87.1
TypeScript version
v5.9.2
Additional context
No response