Awesome Reviewers

When implementing or modifying caching/fetch decisions, treat “fresh vs stale” as a single source of truth derived from the query’s invalidation + stale-time logic. Avoid adding ad-hoc fetch conditions at the observer/queryClient level that bypass (or redefine) TTL semantics.

Concrete rules: 1) Model semantic events (e.g., “background error while data exists”) by updating invalidation state in the query/state layer (e.g., set isInvalidated: true).

Example pattern (central invalidation drives fetch):

// In reducer/state update (when an error happens during a background refetch
// and existing data remains):
return {
  ...state,
  status: 'error',
  isInvalidated: true, // centralize semantic freshness change here
}

// In fetch decision logic (observer/queryObserver):
const shouldFetch = value === 'always' || (value !== false && query.isStale())

Applying these rules prevents subtle regressions like staleTime: 'static' data being refetched due to observer-level error checks, and avoids TTL drift when staleTime or data updates occur.