Skip to content

feat(query-core): add query() and infiniteQuery() methods#9835

Open
DogPawHat wants to merge 70 commits intoTanStack:mainfrom
DogPawHat:implement-simplified-imperitive-methods
Open

feat(query-core): add query() and infiniteQuery() methods#9835
DogPawHat wants to merge 70 commits intoTanStack:mainfrom
DogPawHat:implement-simplified-imperitive-methods

Conversation

@DogPawHat
Copy link
Copy Markdown
Contributor

@DogPawHat DogPawHat commented Nov 1, 2025

🎯 Changes

Implements #9135

  • adds query and infiniteQuery methods as replacements for fetchQuery/fetchInfiniteQuery
  • new methods respect select, enabled and queryFn === skipToken
  • throws errors if enabled === false or queryFn === skipToken and no cached data is able to be returned.
  • updates tests for QueryClient
    • existing scenarios for fetchQuery fetch tests plus the new scenarios introduced (enabled, select, skipToken, static staleTime)
  • adds tests for the queryOptions adaptors
  • added new methods to vue-query QueryClient subclass.
  • added deprecation tags to old methods (fetchQuery, prefetchQuery, ensureQueryData)

TODO when this is merged

  • add new docs

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Added imperative query() and infiniteQuery() methods with preserved option semantics.
  • Documentation

    • Updated guides and examples to prefer query()/infiniteQuery(), showing migration notes and error‑handling patterns (void … .catch(noop)).
  • Types

    • Improved execute-option typings so shared options (select, enabled, page params) narrow returned data correctly.
  • Tests

    • Expanded type and runtime coverage validating new APIs, select/enabled behavior, and pageParam typing.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Nov 1, 2025

🦋 Changeset detected

Latest commit: fff81d9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@tanstack/react-query Minor
@tanstack/query-core Minor
@tanstack/vue-query Minor
@tanstack/react-query-devtools Major
@tanstack/react-query-next-experimental Major
@tanstack/react-query-persist-client Major
@tanstack/angular-query-experimental Patch
@tanstack/preact-query Patch
@tanstack/query-async-storage-persister Patch
@tanstack/query-broadcast-client-experimental Patch
@tanstack/query-persist-client-core Patch
@tanstack/query-sync-storage-persister Patch
@tanstack/solid-query Patch
@tanstack/svelte-query Patch
@tanstack/vue-query-devtools Major
@tanstack/angular-query-persist-client Patch
@tanstack/preact-query-devtools Patch
@tanstack/preact-query-persist-client Patch
@tanstack/solid-query-persist-client Patch
@tanstack/svelte-query-persist-client Patch
@tanstack/solid-query-devtools Patch
@tanstack/svelte-query-devtools Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 1, 2025

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds new imperative QueryClient methods query() and infiniteQuery() with corresponding execute option types, updates infinite pages typing, implements runtime behavior for select/enabled/staleTime, extends type and runtime tests across adapters, and updates framework wrappers and docs to prefer query/infiniteQuery (with recommended .catch(noop) patterns).

Changes

Cohort / File(s) Summary
Core types
packages/query-core/src/types.ts
Add QueryExecuteOptions and InfiniteQueryExecuteOptions; rename FetchInfiniteQueryPagesInfiniteQueryPages and update related types.
Core implementation
packages/query-core/src/queryClient.ts
Add QueryClient.query(...) and QueryClient.infiniteQuery(...) methods: normalize options, resolve enabled/staleTime, conditionally fetch or return cache, apply select; update JSDoc deprecations for legacy imperative APIs.
Core tests (types & runtime)
packages/query-core/src/__tests__/queryClient.test-d.tsx, packages/query-core/src/__tests__/queryClient.test.tsx
Add extensive type-tests for query/infiniteQuery (select, skipToken, enabled, pages/getNextPageParam) and runtime tests for staleTime: 'static', caching, revalidation, and prefetch semantics.
Framework adapters (Vue)
packages/vue-query/src/queryClient.ts, packages/vue-query/src/__tests__/queryClient.test.ts, packages/vue-query/src/__tests__/*
Add overloads for QueryExecuteOptions / InfiniteQueryExecuteOptions and MaybeRefDeep variants; implementations call cloneDeepUnref(options) and delegate to core; tests updated to assert unref behavior.
Framework adapters (other libs) — type tests
packages/*/src/__tests__/*-d.tsx, packages/*/tests/*-d.ts (react, preact, solid, svelte, angular, angular-query-experimental)
Add/extend TypeScript tests verifying query()/infiniteQuery() inference for select, initialPageParam, page types, and that legacy fetch/prefetch ignore select at runtime.
Runtime tests (dedupe / suspension)
packages/react-query/src/__tests__/useQuery.promise.test.tsx
Add Suspense/dedupe test ensuring queryClient.query(...) does not re-run queryFn while a component is suspended via query.promise.
Docs & examples
docs/**, docs/reference/QueryClient.md
Replace examples and guidance from fetchQuery/prefetchQuery to query/infiniteQuery, add migration notes, and recommend discarding promises with void and using .catch(noop) for non-critical prefetches.
Changeset
.changeset/famous-owls-battle.md
Add changeset documenting addition of query() and infiniteQuery() and minor version bumps.

Sequence Diagram(s)

sequenceDiagram
  participant Client as QueryClient
  participant Cache as QueryCache
  participant Fetcher as QueryFn
  participant Selector as Select (optional)
  Client->>Cache: normalize options, resolve enabled & staleTime
  alt disabled && no cache
    Client-->>Client: reject (disabled + no data)
  else enabled && stale
    Client->>Fetcher: call queryFn (with pageParam if infinite)
    Fetcher-->>Client: data
    Client->>Cache: update cache entry
    alt select provided
      Client->>Selector: apply select(data)
      Selector-->>Client: selectedData
      Client-->>Caller: Promise resolves with selectedData
    else
      Client-->>Caller: Promise resolves with data
    end
  else not stale (cache hit)
    Cache-->>Client: cachedData
    alt select provided
      Client->>Selector: apply select(cachedQueryData)
      Selector-->>Client: selectedData
      Client-->>Caller: Promise resolves with selectedData
    else
      Client-->>Caller: Promise resolves with cachedData
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A little rabbit hops with glee,
New queries bloom — query and infinite, whee!
Types lined up and tests all pass,
Docs updated across the grass,
Unref, select, and staleTime set free.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(query-core): add query() and infiniteQuery() methods' clearly and concisely summarizes the main change: adding two new methods to QueryClient.
Description check ✅ Passed The description covers the main changes, implementation details, test updates, and properly marks the required checklist items. All major sections are addressed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Nov 1, 2025

View your CI Pipeline Execution ↗ for commit a6d55fd

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 2s View ↗
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 28s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-05 19:55:56 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Nov 1, 2025

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9835

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9835

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@9835

@tanstack/preact-query-devtools

npm i https://pkg.pr.new/@tanstack/preact-query-devtools@9835

@tanstack/preact-query-persist-client

npm i https://pkg.pr.new/@tanstack/preact-query-persist-client@9835

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9835

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9835

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9835

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9835

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9835

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9835

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9835

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9835

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9835

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9835

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9835

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9835

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9835

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9835

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9835

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9835

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9835

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9835

commit: a6d55fd

@TkDodo
Copy link
Copy Markdown
Collaborator

TkDodo commented Nov 1, 2025

renames fetchQuery and fetchInfiniteQuery to query and infiniteQuery

sorry the idea was not to rename those, but to add new methods and deprecate the old ones. Otherwise, this would be a breaking change.

@codecov
Copy link
Copy Markdown

codecov bot commented Nov 1, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.62%. Comparing base (e907f89) to head (3b0207d).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9835       +/-   ##
===========================================
+ Coverage   45.79%   59.62%   +13.82%     
===========================================
  Files         200      129       -71     
  Lines        8520     5754     -2766     
  Branches     1975     1587      -388     
===========================================
- Hits         3902     3431      -471     
+ Misses       4158     2006     -2152     
+ Partials      460      317      -143     
Components Coverage Δ
@tanstack/angular-query-experimental 93.85% <ø> (ø)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister 43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental 24.39% <ø> (ø)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core 97.34% <93.75%> (-0.04%) ⬇️
@tanstack/query-devtools 3.38% <ø> (ø)
@tanstack/query-persist-client-core 80.00% <ø> (ø)
@tanstack/query-sync-storage-persister 84.61% <ø> (ø)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query 96.34% <ø> (ø)
@tanstack/react-query-devtools 9.25% <ø> (ø)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client 100.00% <ø> (ø)
@tanstack/solid-query 77.81% <ø> (ø)
@tanstack/solid-query-devtools 64.17% <ø> (ø)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query ∅ <ø> (∅)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client ∅ <ø> (∅)
@tanstack/vue-query 71.34% <0.00%> (-0.58%) ⬇️
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DogPawHat DogPawHat force-pushed the implement-simplified-imperitive-methods branch from b3a20d4 to 46d274c Compare November 1, 2025 20:53
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 411f030 and 46d274c.

📒 Files selected for processing (5)
  • .changeset/wise-suns-ask.md (1 hunks)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (2 hunks)
  • packages/query-core/src/__tests__/queryClient.test.tsx (9 hunks)
  • packages/query-core/src/queryClient.ts (6 hunks)
  • packages/vue-query/src/queryClient.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Applied to files:

  • .changeset/wise-suns-ask.md
🧬 Code graph analysis (4)
packages/query-core/src/__tests__/queryClient.test-d.tsx (3)
packages/query-core/src/types.ts (1)
  • InfiniteData (204-207)
packages/query-core/src/queryClient.ts (1)
  • infiniteQuery (395-417)
packages/vue-query/src/queryClient.ts (1)
  • infiniteQuery (328-346)
packages/query-core/src/__tests__/queryClient.test.tsx (2)
packages/query-core/src/utils.ts (2)
  • noop (82-82)
  • sleep (363-367)
packages/query-core/src/types.ts (1)
  • QueryFunction (96-100)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • FetchQueryOptions (491-507)
  • FetchInfiniteQueryOptions (548-565)
  • InfiniteData (204-207)
packages/vue-query/src/types.ts (1)
  • MaybeRefDeep (29-37)
packages/vue-query/src/utils.ts (1)
  • cloneDeepUnref (70-97)
packages/query-core/src/queryClient.ts (2)
packages/query-core/src/utils.ts (1)
  • noop (82-82)
packages/query-core/src/types.ts (5)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • FetchQueryOptions (491-507)
  • FetchInfiniteQueryOptions (548-565)
  • InfiniteData (204-207)
🪛 LanguageTool
.changeset/wise-suns-ask.md

[grammar] ~6-~6: Ensure spelling is correct
Context: ...tanstack/vue-query': minor --- renamed imperitive methods

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (8)
packages/query-core/src/queryClient.ts (5)

140-159: LGTM! ensureQueryData correctly delegates to the new query method.

The internal delegation to query with staleTime: 'static' maintains the expected behavior while utilizing the new method.


336-365: Verify alignment with maintainer expectations regarding API migration strategy.

Per TkDodo's comment, the original intent was to "add new methods and deprecate the old ones to avoid a breaking change, not to remove/rename them outright." While this implementation maintains backward compatibility by keeping fetchQuery as a wrapper, please confirm that making query the primary implementation (rather than keeping fetchQuery as primary and adding query as an alias) aligns with the team's migration strategy.


384-393: LGTM! prefetchQuery correctly delegates to the new query method.

The delegation pattern with .then(noop).catch(noop) properly maintains the fire-and-forget prefetch behavior.


395-417: LGTM! infiniteQuery implementation is clean and consistent.

The method correctly sets the infiniteQueryBehavior and delegates to the query method. The type assertion on line 416 is necessary due to the behavior transformation.


436-452: LGTM! prefetchInfiniteQuery correctly delegates to the new infiniteQuery method.

The delegation pattern maintains the fire-and-forget prefetch behavior.

packages/query-core/src/__tests__/queryClient.test-d.tsx (1)

313-328: LGTM! Type assertions for new methods are comprehensive and correct.

The type checks for query and infiniteQuery methods properly cover both fully typed and untyped scenarios, maintaining consistency with the existing test structure.

Also applies to: 462-477

packages/query-core/src/__tests__/queryClient.test.tsx (1)

11-11: LGTM! Comprehensive test coverage for the new query methods.

The test additions are excellent:

  • Properly imports noop utility for prefetch patterns
  • Marks old test suites with @deprecated comments for clarity
  • Provides thorough coverage of new query and infiniteQuery methods including:
    • Static staleTime behavior
    • Prefetching scenarios
    • Type safety validation
    • Edge cases (cache hits, invalidation, GC, etc.)
  • Maintains parallel structure with legacy tests while validating new functionality

Also applies to: 453-453, 529-620, 622-622, 683-720, 753-753, 928-1100, 1102-1102, 1147-1189, 1191-1191, 1281-1374, 1376-1376, 1426-1477

packages/vue-query/src/queryClient.ts (1)

256-346: LGTM! Vue Query extensions for new methods are well-implemented.

The query and infiniteQuery methods properly:

  • Provide overloads for both plain and MaybeRefDeep options
  • Use cloneDeepUnref to handle Vue's reactive refs correctly
  • Delegate to the parent QueryClient implementation
  • Follow the established pattern used by other methods in this class

@DogPawHat
Copy link
Copy Markdown
Contributor Author

DogPawHat commented Nov 1, 2025

From #9135:

Per default, this should behave like queryClient.fetchQuery does today:

  • it respects staleTime (like any good query should)
  • it returns a Promise you can await.

fetchQuery is still there, it's just a straight passthough for query now

@DogPawHat DogPawHat force-pushed the implement-simplified-imperitive-methods branch from c18dfc0 to 7670b40 Compare November 2, 2025 13:08
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16bed21 and fb9dcdc.

📒 Files selected for processing (8)
  • .changeset/famous-owls-battle.md (1 hunks)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (7 hunks)
  • packages/query-core/src/__tests__/queryClient.test.tsx (9 hunks)
  • packages/query-core/src/queryClient.ts (8 hunks)
  • packages/query-core/src/types.ts (3 hunks)
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (3 hunks)
  • packages/react-query/src/__tests__/queryOptions.test-d.tsx (2 hunks)
  • packages/vue-query/src/queryClient.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-query/src/tests/queryOptions.test-d.tsx
  • packages/react-query/src/tests/infiniteQueryOptions.test-d.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Applied to files:

  • .changeset/famous-owls-battle.md
🧬 Code graph analysis (4)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
  • infiniteQuery (409-431)
packages/query-core/src/types.ts (2)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
packages/query-core/src/queryClient.ts (4)
packages/query-core/src/utils.ts (2)
  • noop (82-82)
  • resolveStaleTime (101-113)
packages/query-core/src/types.ts (7)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • FetchQueryOptions (511-527)
  • InfiniteQueryExecuteOptions (568-586)
  • FetchInfiniteQueryOptions (588-605)
  • InfiniteData (204-207)
packages/query-core/src/query.ts (1)
  • isStale (296-306)
packages/vue-query/src/queryClient.ts (1)
  • query (294-314)
packages/query-core/src/__tests__/queryClient.test.tsx (2)
packages/query-core/src/utils.ts (2)
  • noop (82-82)
  • sleep (363-367)
packages/query-core/src/types.ts (1)
  • QueryFunction (96-100)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteQueryExecuteOptions (568-586)
  • InfiniteData (204-207)
packages/vue-query/src/types.ts (1)
  • MaybeRefDeep (29-37)
packages/vue-query/src/utils.ts (1)
  • cloneDeepUnref (70-97)
🪛 Biome (2.1.2)
packages/query-core/src/__tests__/queryClient.test-d.tsx

[error] 342-342: Const declarations must have an initialized value.

This variable needs to be initialized.

(parse)


[error] 342-342: Shouldn't redeclare 'infiniteQueryOptions'. Consider to delete it or rename it.

'infiniteQueryOptions' is defined here:

(lint/suspicious/noRedeclare)


[error] 441-441: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 443-443: Shouldn't redeclare 'infiniteQuery'. Consider to delete it or rename it.

'infiniteQuery' is defined here:

(lint/suspicious/noRedeclare)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (7)
packages/query-core/src/__tests__/queryClient.test-d.tsx (7)

161-172: LGTM!

The test correctly verifies that fetchQuery does not accept the select option, maintaining backward compatibility as intended in the PR design.


174-227: LGTM!

The tests correctly verify:

  • select option is not allowed on fetchInfiniteQuery (backward compatibility)
  • pages parameter is properly typed
  • getNextPageParam is required when pages is specified

229-239: LGTM!

The test correctly verifies that the new query method accepts the select option, which is the key differentiator from the fetchQuery compatibility wrapper.


242-257: Verify whether select should be allowed on infiniteQuery.

This test asserts that select is not allowed on infiniteQuery, but:

  1. Lines 336-339 show InfiniteQueryExecuteOptions being used with a select option successfully
  2. Unlike the fetchInfiniteQuery test (line 183), there's no @ts-expect-error annotation on the select property (line 249)

Based on the implementation where infiniteQuery delegates to query (which supports select), it appears select should be allowed. Please clarify the intended behavior and add the @ts-expect-error annotation if select is truly not supported, or update the test description if it is supported.


428-429: LGTM!

The type check correctly verifies that query returns the expected TData type.


578-579: LGTM!

The type check correctly verifies that query returns unknown when called with untyped options.


583-593: LGTM!

The type checks correctly verify the return types for fetchInfiniteQuery and infiniteQuery with untyped options, both returning InfiniteData<unknown, unknown>.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb9dcdc and 3b33d44.

📒 Files selected for processing (2)
  • .changeset/famous-owls-battle.md (1 hunks)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/famous-owls-battle.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (3)
packages/query-core/src/queryClient.ts (2)
  • QueryClient (63-692)
  • infiniteQuery (409-431)
packages/vue-query/src/queryClient.ts (2)
  • QueryClient (39-589)
  • infiniteQuery (348-366)
packages/query-core/src/types.ts (2)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b33d44 and a24433b.

📒 Files selected for processing (1)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.049Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
  • infiniteQuery (409-431)
packages/query-core/src/types.ts (2)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (5)
packages/query-core/src/__tests__/queryClient.test-d.tsx (5)

13-13: LGTM!

The addition of InfiniteQueryExecuteOptions to the imports aligns with the new public API surface introduced in this PR.


161-172: LGTM!

This test correctly validates that the legacy fetchQuery method does not support the select option, with proper use of @ts-expect-error to enforce the type constraint.


174-227: LGTM!

The tests for fetchInfiniteQuery correctly validate the legacy behavior, including:

  • Properly rejecting select option with @ts-expect-error
  • Validating the pages option with correct type expectations
  • Enforcing required parameter constraints

229-239: LGTM!

This test correctly validates that the new query method supports the select option for data transformation, properly demonstrating the enhanced functionality compared to the legacy fetchQuery.


328-336: LGTM!

The integration of the new query and infiniteQuery methods into the fully-typed and untyped test sections is correct:

  • Proper usage of InfiniteQueryExecuteOptions<TData, TError> type
  • Correct type expectations for return values
  • Good coverage of both typed and untyped variants

Also applies to: 422-423, 434-435, 569-570, 581-584

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (1)

205-214: Fix misleading test title.

The test uses assertType without @ts-expect-error, meaning it's verifying that passing getNextPageParam without pages is allowed (per the InfiniteQueryPages union's { pages?: never } branch). The title incorrectly says "should not allow".

Apply this diff:

-  it('should not allow passing getNextPageParam without pages', () => {
+  it('should allow passing getNextPageParam without pages', () => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a24433b and fa6f86f.

📒 Files selected for processing (2)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (7 hunks)
  • packages/query-core/src/types.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.049Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.049Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/types.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/types.ts
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/queryClient.test-d.tsx (2)
packages/query-core/src/queryClient.ts (1)
  • infiniteQuery (409-431)
packages/query-core/src/types.ts (2)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (7)
packages/query-core/src/types.ts (3)

491-509: LGTM: QueryExecuteOptions introduces select support correctly.

The new QueryExecuteOptions interface properly introduces the select transformation flow via the TQueryData generic. The data flows as TQueryFnData (raw) → TQueryData (intermediate) → TData (final via select). The staleTime correctly uses TQueryData since staleness should be determined from the query's stored data, not the transformed result.


511-528: LGTM: FetchQueryOptions maintains backward compatibility.

The refactor to make FetchQueryOptions an alias that omits select from QueryExecuteOptions is correct. Passing TData as both the 3rd and 4th generics (TData, TData) ensures no transformation layer exists when select is omitted, maintaining the original behavior of fetchQuery.


568-586: LGTM: InfiniteQueryExecuteOptions properly extends execute options.

The type correctly:

  • Omits initialPageParam from QueryExecuteOptions (which has initialPageParam?: never)
  • Re-adds it via InitialPageParam<TPageParam> with the proper type
  • Uses InfiniteData<TQueryFnData, TPageParam> as the intermediate data shape
  • Includes InfiniteQueryPages discriminated union to enforce the pages/getNextPageParam constraint
packages/query-core/src/__tests__/queryClient.test-d.tsx (4)

161-172: LGTM: Correctly verifies fetchQuery rejects select.

The test properly uses @ts-expect-error to confirm that the legacy fetchQuery method does not support the select option, maintaining backward compatibility.

Based on learnings.


229-239: LGTM: Correctly verifies query accepts select.

The test confirms that the new query method supports the select option for data transformation, using assertType (without @ts-expect-error) to validate this is allowed.

Based on learnings.


241-257: LGTM: Correctly verifies infiniteQuery accepts select.

The test confirms that the new infiniteQuery method supports the select option for transforming infinite query data, using assertType (without @ts-expect-error) to validate this is allowed.

Based on learnings.


328-336: LGTM: infiniteQueryOptions properly typed.

The variable correctly uses InfiniteQueryExecuteOptions<TData, TError> with defaults for remaining generics. The getNextPageParam callback properly receives lastPage typed as TData.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/query-core/src/queryClient.ts (1)

428-450: Implementation delegates correctly, but consider type-safe alternatives to the cast.

The method properly sets infiniteQueryBehavior before delegating to query. The as any cast on line 449 bypasses type safety—consider whether tighter generic constraints or a helper could eliminate it.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa6f86f and 6a3c2ed.

📒 Files selected for processing (2)
  • packages/query-core/src/queryClient.ts (5 hunks)
  • packages/query-core/src/types.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/types.ts
  • packages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (3)
packages/query-core/src/types.ts (6)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteQueryExecuteOptions (568-586)
  • FetchInfiniteQueryOptions (588-605)
  • InfiniteData (204-207)
packages/vue-query/src/queryClient.ts (1)
  • query (294-314)
packages/query-core/src/utils.ts (1)
  • resolveStaleTime (101-113)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (4)
packages/query-core/src/types.ts (2)

491-509: LGTM! Well-designed interface for query execution options.

The interface correctly separates TQueryData from TData to enable optional select transformation, explicitly prevents initialPageParam for single queries, and provides clear documentation for staleTime behavior.


561-586: LGTM! Clean type composition for infinite query execution.

The discriminated union for InfiniteQueryPages and the composition strategy for InfiniteQueryExecuteOptions (omitting the never field then adding the required version) correctly enforces that infinite queries must provide initialPageParam.

packages/query-core/src/queryClient.ts (2)

343-384: LGTM! Core query execution logic is sound.

The method correctly handles stale-time checking, optional data fetching, and select transformation. The double cast as unknown as TData on line 383 is a TypeScript workaround when no select is provided (TData defaults to TQueryData), though it's safe in practice.


452-468: Fix: Missing options.behavior setup before delegation to fetchQuery.

The fetchInfiniteQuery method must set options.behavior before delegating to fetchQuery, matching the pattern used in infiniteQuery (lines 443-448) and ensureInfiniteQueryData (lines 503-508). Without this, infinite query pagination will not work correctly.

 fetchInfiniteQuery<
   TQueryFnData,
   TError = DefaultError,
   TData = TQueryFnData,
   TQueryKey extends QueryKey = QueryKey,
   TPageParam = unknown,
 >(
   options: FetchInfiniteQueryOptions<
     TQueryFnData,
     TError,
     TData,
     TQueryKey,
     TPageParam
   >,
 ): Promise<InfiniteData<TData, TPageParam>> {
+  options.behavior = infiniteQueryBehavior<
+    TQueryFnData,
+    TError,
+    TData,
+    TPageParam
+  >(options.pages)
   return this.fetchQuery(options as any)
 }
⛔ Skipped due to learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/query-core/src/queryClient.ts (1)

428-450: Fix the type error and avoid as any assertion.

Two issues need to be addressed:

  1. Pipeline failure (Line 443): The type error indicates that QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, readonly unknown[]> is not assignable to QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>. This suggests a mismatch in the query key type constraint.

  2. Line 449: The as any type assertion bypasses type safety and hides potential type errors. This indicates that the types don't align properly between InfiniteQueryExecuteOptions and QueryExecuteOptions.

The type system should properly model the relationship between these option types without requiring unsafe casts. Please investigate:

  • Whether the QueryExecuteOptions type needs to be adjusted to properly accept infinite query options
  • Whether the generic constraints need to be refined to make the types compatible
  • Alternative approaches that maintain type safety
#!/bin/bash
# Check how behavior property is typed and used
ast-grep --pattern $'behavior: QueryBehavior<$$$>'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a3c2ed and 1338e8e.

📒 Files selected for processing (1)
  • packages/query-core/src/queryClient.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (3)
packages/query-core/src/types.ts (6)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteQueryExecuteOptions (568-586)
  • FetchInfiniteQueryOptions (588-605)
  • InfiniteData (204-207)
packages/vue-query/src/queryClient.ts (1)
  • query (294-314)
packages/query-core/src/utils.ts (1)
  • resolveStaleTime (101-113)
🪛 GitHub Actions: PR
packages/query-core/src/queryClient.ts

[error] 443-443: Type 'QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, readonly unknown[]>' is not assignable to type 'QueryBehavior<TQueryFnData, TError, InfiniteData<TQueryFnData, TPageParam>, TQueryKey>'.

🔇 Additional comments (2)
packages/query-core/src/queryClient.ts (2)

28-28: LGTM!

The new type imports support the query and infiniteQuery method signatures correctly.

Also applies to: 37-37


373-383: Verify data handling assumptions in the query method implementation.

The technical concerns in the review are valid: when isStale is false, query.state.data could be undefined (initialized without initialData), and this would be passed to the select function without a guard. The type signature select?: (data: TQueryData) => TData expects defined data, but the cast on line 375 (as TQueryData) doesn't guarantee it at runtime.

However, test cases across the codebase show select always receives properly typed, defined data—no scenario in tests passes undefined to the selector. This suggests either:

  1. The scenario is prevented by caller contracts (e.g., always providing initialData or ensuring fetch completes first)
  2. The stale-time logic prevents isStale=false when data is undefined
  3. This is an edge case not covered by tests

Confirm whether adding a guard (e.g., if (!queryData) return queryData as TData) is necessary, or if the current design intentionally relies on caller responsibility to provide valid initial state.

@DogPawHat DogPawHat force-pushed the implement-simplified-imperitive-methods branch from 1338e8e to 8c46d9e Compare November 26, 2025 14:56
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/query-core/src/queryClient.ts (1)

428-452: Restore infiniteQueryBehavior wiring for fetchInfiniteQuery and reduce as any surface

Currently, only infiniteQuery and ensureInfiniteQueryData attach infiniteQueryBehavior, while fetchInfiniteQuery now delegates straight to fetchQuery without setting options.behavior:

fetchInfiniteQuery(...) {
  return this.fetchQuery(options as any)
}

In the published build, fetchInfiniteQuery sets options.behavior = infiniteQueryBehavior(options.pages) before calling fetchQuery, which is what gives it proper infinite paging semantics (using pages, pageParams, and getNextPageParam). (impactic.de) Dropping that here likely breaks existing fetchInfiniteQuery behavior and will make tests like “should return infinite query data”/“should prefetch multiple pages” incorrect at runtime.

I’d strongly suggest restoring the behavior setup, e.g.:

  fetchInfiniteQuery<
    TQueryFnData,
    TError = DefaultError,
    TData = TQueryFnData,
    TQueryKey extends QueryKey = QueryKey,
    TPageParam = unknown,
  >(
    options: FetchInfiniteQueryOptions<
      TQueryFnData,
      TError,
      TData,
      TQueryKey,
      TPageParam
    >,
  ): Promise<InfiniteData<TData, TPageParam>> {
    options.behavior = infiniteQueryBehavior<
      TQueryFnData,
      TError,
      TData,
      TPageParam
    >(options.pages)
    return this.fetchQuery(options as any)
  }

On top of that, the three as any casts (this.query(options as any), this.fetchQuery(options as any), this.ensureQueryData(options as any)) are understandable given the generic differences between execute/fetch option types, but they do punch a hole through type safety. If feasible, consider a small internal helper or tightening the generic relationships between QueryExecuteOptions, InfiniteQueryExecuteOptions, FetchQueryOptions, and FetchInfiniteQueryOptions so these calls can be expressed without any (or at least with a narrower cast and a brief comment on why it’s safe).

Also applies to: 470-486, 488-511

🧹 Nitpick comments (1)
packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (1)

53-66: Type tests correctly encode select behavior for infinite paths

The new tests nicely capture the intended distinctions:

  • useInfiniteQuery, useSuspenseInfiniteQuery, and QueryClient.infiniteQuery all see select and return the transformed Array<string> type.
  • fetchInfiniteQuery still yields InfiniteData<string, number> even when given options that include select, matching the legacy “no select” behavior for fetch APIs.

Only tiny nit: the “known issue” comment in the suspense test still mentions useInfiniteQuery, but that’s cosmetic.

Also applies to: 79-92, 93-117, 130-142

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1338e8e and 8c46d9e.

📒 Files selected for processing (8)
  • .changeset/famous-owls-battle.md (1 hunks)
  • packages/query-core/src/__tests__/queryClient.test-d.tsx (7 hunks)
  • packages/query-core/src/__tests__/queryClient.test.tsx (9 hunks)
  • packages/query-core/src/queryClient.ts (5 hunks)
  • packages/query-core/src/types.ts (3 hunks)
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx (3 hunks)
  • packages/react-query/src/__tests__/queryOptions.test-d.tsx (2 hunks)
  • packages/vue-query/src/queryClient.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/famous-owls-battle.md
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.

Applied to files:

  • packages/react-query/src/__tests__/queryOptions.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/vue-query/src/queryClient.ts
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/react-query/src/__tests__/queryOptions.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/vue-query/src/queryClient.ts
  • packages/query-core/src/types.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/react-query/src/__tests__/queryOptions.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/query-core/src/queryClient.ts
🧬 Code graph analysis (3)
packages/query-core/src/__tests__/queryClient.test-d.tsx (1)
packages/query-core/src/types.ts (2)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
packages/query-core/src/queryClient.ts (2)
packages/query-core/src/types.ts (6)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteQueryExecuteOptions (568-586)
  • FetchInfiniteQueryOptions (588-605)
  • InfiniteData (204-207)
packages/query-core/src/utils.ts (1)
  • resolveStaleTime (112-124)
packages/vue-query/src/queryClient.ts (3)
packages/query-core/src/types.ts (5)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteQueryExecuteOptions (568-586)
  • InfiniteData (204-207)
packages/vue-query/src/types.ts (1)
  • MaybeRefDeep (29-37)
packages/vue-query/src/utils.ts (1)
  • cloneDeepUnref (70-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (8)
packages/query-core/src/types.ts (1)

491-509: New execute option types align well with observer options and infinite semantics

QueryExecuteOptions and InfiniteQueryExecuteOptions are wired correctly: using TQueryData for staleTime and select matches how defaultQueryOptions and resolveStaleTime operate, and InfiniteQueryPages cleanly enforces the pages/getNextPageParam pairing while being reused by both execute and fetch infinite options. This should give query/infiniteQuery the right type-level behavior without impacting existing Fetch* callers.

Also applies to: 561-587, 588-605

packages/react-query/src/__tests__/queryOptions.test-d.tsx (1)

58-66: query vs fetchQuery select behavior is well covered

The added tests clearly distinguish the new query API (including select transformations) from the legacy fetchQuery (which returns the raw number even when given options that contain select). This matches the intended separation between the new and old imperative entry points.

Also applies to: 76-95

packages/query-core/src/__tests__/queryClient.test-d.tsx (2)

161-172: Type tests cleanly separate select support between legacy and new APIs

The new blocks for fetchQuery, fetchInfiniteQuery, query, and infiniteQuery correctly encode the contract:

  • fetchQuery/fetchInfiniteQuery reject select at the option level via @ts-expect-error.
  • query/infiniteQuery accept select and assert the transformed data types.

This gives solid type-level coverage for the migration story from the old fetch* APIs to the new imperative methods.

Also applies to: 175-192, 229-257


193-203: Infinite execute/fetch options generics are exercised thoroughly

The updated tests around passing pages, using { count: number } pages, and the “fully typed usage” blocks validate that:

  • FetchInfiniteQueryOptions and InfiniteQueryExecuteOptions expose lastPage as TData in getNextPageParam.
  • infiniteQuery and fetchInfiniteQuery both resolve to InfiniteData<TData, TPageParam> (or InfiniteData<unknown, unknown> in the untyped case).

This gives good confidence that the new infinite-execute types integrate correctly with QueryClient’s generics.

Also applies to: 259-269, 328-337, 422-435, 569-585

packages/query-core/src/__tests__/queryClient.test.tsx (2)

529-620: Static staleTime behavior for query/infiniteQuery is well specified

The new “with static staleTime” suites for both query and infiniteQuery clearly pin down the behavior:

  • Cached data (including falsy values) is returned without re-fetching when staleTime is 'static'.
  • Missing queries invoke queryFn once.
  • Providing initialData short-circuits network calls.
  • A second call with staleTime: 0 drives an explicit background revalidation, as verified via noop and cache assertions.

This is a strong regression suite for the new imperative surface.

Also applies to: 683-720


928-1106: Runtime tests give good confidence in new query/infiniteQuery entry points

The added query/infiniteQuery suites (including “used for prefetching”) thoroughly mirror the legacy fetchQuery/prefetch* behavior:

  • No-retry-by-default semantics, gcTime handling, and static staleTime cache hits are preserved.
  • Infinite flows still produce the expected InfiniteData shapes, including multi-page prefetch and early termination via getNextPageParam.
  • Prefetch-style usages (.catch(noop)) ensure that using query/infiniteQuery purely for seeding the cache continues to work.

Overall, the tests look well aligned with the intended migration path from the deprecated fetch* methods to the new APIs.

Also applies to: 1153-1195, 1287-1380, 1432-1483

packages/vue-query/src/queryClient.ts (1)

19-37: Vue QueryClient query/infiniteQuery wrappers are consistent and type-safe

The new query and infiniteQuery overloads:

  • Reuse the core QueryExecuteOptions / InfiniteQueryExecuteOptions generics correctly.
  • Preserve the Vue adapter’s MaybeRefDeep + cloneDeepUnref pattern so refs and getter-based queryKeys are handled before delegating.
  • Return the expected Promise<TData> / Promise<InfiniteData<TData, TPageParam>> types, matching the core client.

This keeps the Vue surface in lockstep with the new imperative APIs.

Also applies to: 258-366

packages/query-core/src/queryClient.ts (1)

343-384: query implementation correctly layers select on top of legacy fetch semantics

The new query method:

  • Runs through defaultQueryOptions, preserves the “no retry by default” behavior from fetchQuery, and uses resolveStaleTime with QueryExecuteOptions.staleTime typed on TQueryData.
  • Fetches when isStaleByTime is true, otherwise returns query.state.data from cache.
  • Applies select once, purely at the imperative layer, without mutating the stored query data.

This matches the intended contract for the new imperative API and is well covered by the added runtime and type tests.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/query-core/src/queryClient.ts (1)

428-454: Type assertion bypasses type safety.

Line 453 uses as any when delegating to this.query, which bypasses TypeScript's type checking. While this mirrors the existing pattern in fetchInfiniteQuery (Line 477), the cast suggests that InfiniteQueryExecuteOptions and QueryExecuteOptions aren't properly aligned.

Consider refactoring to eliminate the cast by:

  • Ensuring type compatibility between the two option types
  • Extracting a shared internal helper that both methods can call with appropriate generic bounds
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c46d9e and a16e585.

📒 Files selected for processing (3)
  • packages/query-core/src/queryClient.ts (4 hunks)
  • packages/query-core/src/types.ts (3 hunks)
  • packages/vue-query/src/queryClient.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts
  • packages/vue-query/src/queryClient.ts
📚 Learning: 2025-11-22T09:06:05.219Z
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.

Applied to files:

  • packages/query-core/src/queryClient.ts
  • packages/vue-query/src/queryClient.ts
📚 Learning: 2025-08-19T03:18:18.303Z
Learnt from: oscartbeaumont
Repo: TanStack/query PR: 9564
File: packages/solid-query-devtools/src/production.tsx:2-3
Timestamp: 2025-08-19T03:18:18.303Z
Learning: In the solid-query-devtools package, the codebase uses a pattern of type-only default imports combined with typeof for component type annotations (e.g., `import type SolidQueryDevtoolsComp from './devtools'` followed by `typeof SolidQueryDevtoolsComp`). This pattern is consistently used across index.tsx and production.tsx files, and the maintainers prefer consistency over changing this approach.

Applied to files:

  • packages/query-core/src/queryClient.ts
🧬 Code graph analysis (1)
packages/query-core/src/queryClient.ts (4)
packages/query-core/src/types.ts (5)
  • DefaultError (47-51)
  • QueryKey (53-61)
  • QueryExecuteOptions (491-509)
  • InfiniteData (204-207)
  • InfiniteQueryExecuteOptions (568-586)
packages/query-core/src/query.ts (1)
  • isStale (296-306)
packages/query-core/src/utils.ts (1)
  • resolveStaleTime (112-124)
packages/query-core/src/infiniteQueryBehavior.ts (1)
  • infiniteQueryBehavior (11-133)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (2)
packages/query-core/src/queryClient.ts (1)

343-384: LGTM! The query method logic is sound.

The implementation correctly:

  • Defaults retry to false (matching fetchQuery behavior)
  • Checks staleness via resolveStaleTime
  • Fetches when stale or returns cached data
  • Applies select transformation when provided

The double cast at Line 383 (as unknown as TData) is safe given that TData defaults to TQueryData when select is not provided, though it's overly defensive.

Based on learnings, the new query method correctly supports the select option for data transformation.

packages/query-core/src/types.ts (1)

491-509: LGTM! Type definitions are well-structured.

The new type definitions are correctly designed:

  • QueryExecuteOptions (491-509): Properly extends QueryOptions with required queryKey, adds select for data transformation, and includes staleTime for staleness control
  • InfiniteQueryPages (561-566): Clean discriminated union that allows optional pages specification or requires getNextPageParam when pages are specified
  • InfiniteQueryExecuteOptions (568-586): Well-composed type combining QueryExecuteOptions, InitialPageParam, and InfiniteQueryPages
  • FetchInfiniteQueryOptions (605): Updated to reuse InfiniteQueryPages, improving consistency

Based on learnings, the new types correctly support the select option for data transformation in query and infiniteQuery methods.

Also applies to: 561-586, 605-605

TQueryFnData,
TError = DefaultError,
TData = TQueryFnData,
TData = InfiniteData<TQueryFnData>,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to match the options used by react query queryOptions but not InfiniteQueryObserverOptions in query-core types.ts.

@DogPawHat
Copy link
Copy Markdown
Contributor Author

Deprecation tags and new tests added

@DogPawHat
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
docs/framework/vue/guides/ssr.md (2)

59-66: ⚠️ Potential issue | 🟠 Major

Fix undefined suspense usage in both Nuxt examples.

Both examples call await suspense() but the bound variable is missing/misspelled ({ data } only in one case, suspsense typo in the other).

Suggested doc fix
-const { data } = useQuery({
+const { data, suspense } = useQuery({
  queryKey: ['test'],
  queryFn: fetcher,
})
-const { data, refetch, suspsense } = useQuery(
+const { data, refetch, suspense } = useQuery(

Also applies to: 143-161

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/vue/guides/ssr.md` around lines 59 - 66, The examples call
await suspense() but never bind or import suspense (and one example misspells it
as suspsense); update both Nuxt snippets to destructure suspense from
useSuspense or the appropriate composable (e.g., const { data, suspense } =
useQuery(...) or import/useSuspense()) and fix the typo (suspsense → suspense),
then ensure onServerPrefetch awaits the correctly bound suspense so suspense is
defined when used; reference useQuery, suspense, onServerPrefetch, and the
misspelled suspsense to locate the fixes.

117-187: ⚠️ Potential issue | 🟠 Major

Repair the corrupted Nuxt 2 markdown/code block.

This section currently mixes prose into fenced code and includes malformed tokens (i````, queryma`, embedded Vite SSR text), making the example unusable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/vue/guides/ssr.md` around lines 117 - 187, The Nuxt 2 example
block is corrupted and must be split and fixed: restore the pages/todos.vue
fenced block (ensure the <script> uses correct symbols: destructure useQuery
returns as { data, refetch, suspense } not "suspsense", call await suspense()
inside onServerPrefetch, set ssrContext.nuxt.vueQueryState =
dehydrate(queryClient), and make the second useQuery key an array ['todos2']);
remove the stray "i```" and stray tokens and then place the Vite SSR snippet
into its own separate fenced JS block, fixing typos like "queryma" → "suspense"
and ensuring usage of viteSSR, QueryClient, VueQueryPlugin, hydrate/dehydrate
are shown clearly and syntactically valid.
docs/reference/QueryClient.md (1)

111-128: ⚠️ Potential issue | 🟠 Major

Update infiniteQuery documentation to document select support and its effect on the return type.

The infiniteQuery method accepts the same options as the query method, including select for transforming the returned data. When select is provided, the return type becomes Promise<TData> (the selected type), not the fixed Promise<InfiniteData<TData, TPageParam>> shown in the docs. This needs to be documented explicitly, similar to how the query method states "Respects select. The promise resolves with the selected value."

Current documentation (lines 111-128)
`fetchInfiniteQuery` is similar to `fetchQuery` but can be used to fetch and cache an infinite query.

```tsx
try {
  const data = await queryClient.infiniteQuery({ queryKey, queryFn })
  console.log(data.pages)
} catch (error) {
  console.log(error)
}

Options

The options for fetchInfiniteQuery are exactly the same as those of fetchQuery.

Returns

  • Promise<InfiniteData<TData, TPageParam>>
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/reference/QueryClient.md around lines 111 - 128, Update the
fetch/infinite query docs for infiniteQuery/fetchInfiniteQuery to state that the
method accepts the same options as query/queryFn (including select) and that it
"Respects select" — when a select is provided the resolved promise returns the
selected type (Promise) instead of the raw
Promise<InfiniteData<TData, TPageParam>); update the Returns section to reflect
the conditional return type and add a short example note showing that selected
value is returned when using select.


</details>

</blockquote></details>

</blockquote></details>
🧹 Nitpick comments (2)
docs/framework/react/guides/prefetching.md (1)

215-215: Minor style issue: "inside of" is redundant.

Consider simplifying "inside of" to "inside" for cleaner prose.

-Another way is to prefetch inside of the query function.
+Another way is to prefetch inside the query function.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/prefetching.md` at line 215, Change the phrasing
"inside of" to "inside" in the sentence that currently reads "Another way is to
prefetch inside of the query function." within the prefetching guide; update it
to "Another way is to prefetch inside the query function." to remove the
redundant "of" and improve prose.
docs/framework/react/guides/advanced-ssr.md (1)

119-124: Consider defining or importing noop in code examples.

The noop function is used throughout these examples but never defined or imported. Readers unfamiliar with this pattern may be confused. Consider adding a brief note or showing the definition.

// Define noop as: const noop = () => {}
// Or import from a utility library
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/advanced-ssr.md` around lines 119 - 124, The
example uses an undefined noop in the queryClient.query(...).catch(noop) call;
define or import noop so the snippet is self-contained (e.g., add a small
utility definition or import at the top) and ensure the example shows where it
comes from; update the example block containing queryClient, query, getPosts and
the .catch(noop) call to include a reference to the noop definition or an import
statement so readers aren’t confused.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/framework/angular/guides/query-options.md`:
- Line 41: The example calls
queryClient.query(this.queries.post(23)).catch(noop) but noop is not defined;
replace the undefined noop with an inline no-op error handler (e.g., a lambda
that accepts the error and does nothing) so the snippet is self-contained—update
the call to use .catch(err => { /* no-op */ }) or .catch(() => {}) referencing
queryClient.query and this.queries.post to locate the line.

In `@docs/framework/angular/typescript.md`:
- Around line 223-224: Update the runtime behavior note to reflect that legacy
APIs now delegate to query: change the sentence that claims fetchQuery and
prefetchQuery "ignore `select` and `enabled` at runtime" to state that
fetchQuery and prefetchQuery delegate to queryClient.query (via query) and
therefore honor `select` and `enabled` at runtime; reference the symbols
fetchQuery, prefetchQuery, and queryClient.query (or query) so readers know
which implementation now enforces those options.

In `@docs/framework/react/guides/migrating-to-v5.md`:
- Around line 55-87: Replace the placeholder token INSERT_FUTURE_V5_MINOR in the
sentence "deprecated as of Tanstack Query INSERT_FUTURE_V5_MINOR" with the
actual release version string you are targeting (e.g., "v5.<minor>" or the exact
minor version being released); ensure the final sentence reads something like
"deprecated as of Tanstack Query v5.X" and leave the migration examples
(fetchQuery → query, prefetchQuery → query(...).catch(noop), ensureQueryData →
query({ ..., staleTime: 'static' }), etc.) unchanged.

In `@docs/framework/react/guides/query-options.md`:
- Line 28: The example uses queryClient.query(groupOptions(23)) which can return
a rejected Promise and cause unhandled rejections; update the snippet to perform
the call as a fire-and-forget with error swallowing (e.g.,
queryClient.query(groupOptions(23)).catch(noop)) so failures are caught, and
apply the same change to the other occurrences of the pattern (references:
queryClient.query, groupOptions, .catch(noop)).

In `@docs/framework/solid/guides/prefetching.md`:
- Line 89: Change the wording in the sentence "Another way is to prefetch inside
of the query function." to remove the redundant "of" so it reads "Another way is
to prefetch inside the query function." Locate that sentence in the content
where the phrase "prefetch inside of the query function" appears and update it
accordingly.
- Line 244: The article prefetch call currently swallows errors by using
.catch(noop) on queryClient.query(articleQueryOptions); remove the .catch(noop)
so the awaited queryClient.query(articleQueryOptions) can reject and let the
route error boundary handle failures. Locate the call to queryClient.query with
the articleQueryOptions symbol and simply await it without attaching a catch,
ensuring loader-critical errors propagate to the router/errorComponent.

In `@docs/framework/svelte/ssr.md`:
- Line 10: The SSR example uses enabled: browser which disables queries on the
server and causes queryClient.query to reject and be swallowed by .catch(noop);
update the example so server-side preloading explicitly overrides the enabled
flag when calling queryClient.query (or adjust QueryClient defaultOptions for
server use) so that queryClient.query runs during SSR instead of being gated by
browser; reference the QueryClient setup, the enabled: browser flag, and the
queryClient.query(...) call (and the noop catch) and ensure the server prefetch
path sets enabled: true (or removes the browser guard) so cached-by-query
behavior is reliable.

In `@docs/reference/QueryClient.md`:
- Line 99: The documentation contains links using removed fragment anchors
(e.g., `#queryclientensurequerydata` and `#queryclientfetchquery`) that break
navigation; update the link targets for the mentions of
queryClient.ensureQueryData and queryClient.fetchQuery so they point to the
current headings (or to the main QueryClient reference) instead of the deleted
fragments—replace the broken `[...] (`#queryclientensurequerydata`)` and
`(`#queryclientfetchquery`)` fragments with the correct heading anchors or with
non-fragment links to the appropriate section (and make the same correction at
the other occurrence noted around line 124).
- Around line 66-67: Update the intro sentence so it refers to queryClient.query
rather than fetchQuery: change the sentence that currently reads "`fetchQuery`
is an asynchronous method..." to mention `queryClient.query` and that it is an
async method which resolves with data or throws an error, so the heading
`queryClient.query` and the code example match the description.

In `@packages/query-core/src/queryClient.ts`:
- Around line 374-379: The check currently treats both null and undefined as “no
cached data”; update the condition so only undefined is treated as missing
cache: change the guard that reads `if (!isEnabled && query.state.data == null)`
to test for `query.state.data === undefined` (i.e., `if (!isEnabled &&
query.state.data === undefined)`) so a legitimately cached null value is
accepted; update the relevant block around query.state.data and
defaultedOptions.queryHash in queryClient.ts (the code handling disabled
queries) to use this strict undefined check.

In `@packages/vue-query/src/queryClient.ts`:
- Around line 527-529: Update the deprecation JSDoc for prefetchInfiniteQuery to
avoid suggesting `void queryClient.infiniteQuery(options)` (which can create
unhandled rejections); instead state the correct alternative: call
`queryClient.infiniteQuery(options).catch(noop)` (or explicitly swallow errors
with `.catch(noop)`) and keep the deprecation notice on prefetchInfiniteQuery
(also apply the same wording change to the second occurrence). Locate the
comment blocks around prefetchInfiniteQuery and replace the existing hint text
with the corrected wording referencing
queryClient.infiniteQuery(options).catch(noop).

---

Outside diff comments:
In `@docs/framework/vue/guides/ssr.md`:
- Around line 59-66: The examples call await suspense() but never bind or import
suspense (and one example misspells it as suspsense); update both Nuxt snippets
to destructure suspense from useSuspense or the appropriate composable (e.g.,
const { data, suspense } = useQuery(...) or import/useSuspense()) and fix the
typo (suspsense → suspense), then ensure onServerPrefetch awaits the correctly
bound suspense so suspense is defined when used; reference useQuery, suspense,
onServerPrefetch, and the misspelled suspsense to locate the fixes.
- Around line 117-187: The Nuxt 2 example block is corrupted and must be split
and fixed: restore the pages/todos.vue fenced block (ensure the <script> uses
correct symbols: destructure useQuery returns as { data, refetch, suspense } not
"suspsense", call await suspense() inside onServerPrefetch, set
ssrContext.nuxt.vueQueryState = dehydrate(queryClient), and make the second
useQuery key an array ['todos2']); remove the stray "i```" and stray tokens and
then place the Vite SSR snippet into its own separate fenced JS block, fixing
typos like "queryma" → "suspense" and ensuring usage of viteSSR, QueryClient,
VueQueryPlugin, hydrate/dehydrate are shown clearly and syntactically valid.

In `@docs/reference/QueryClient.md`:
- Around line 111-128: Update the fetch/infinite query docs for
infiniteQuery/fetchInfiniteQuery to state that the method accepts the same
options as query/queryFn (including select) and that it "Respects select" — when
a select is provided the resolved promise returns the selected type
(Promise<TSelected>) instead of the raw Promise<InfiniteData<TData,
TPageParam>); update the Returns section to reflect the conditional return type
and add a short example note showing that selected value is returned when using
select.

---

Nitpick comments:
In `@docs/framework/react/guides/advanced-ssr.md`:
- Around line 119-124: The example uses an undefined noop in the
queryClient.query(...).catch(noop) call; define or import noop so the snippet is
self-contained (e.g., add a small utility definition or import at the top) and
ensure the example shows where it comes from; update the example block
containing queryClient, query, getPosts and the .catch(noop) call to include a
reference to the noop definition or an import statement so readers aren’t
confused.

In `@docs/framework/react/guides/prefetching.md`:
- Line 215: Change the phrasing "inside of" to "inside" in the sentence that
currently reads "Another way is to prefetch inside of the query function."
within the prefetching guide; update it to "Another way is to prefetch inside
the query function." to remove the redundant "of" and improve prose.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0ebc393-27f9-41e4-8ea5-b1f0e714f507

📥 Commits

Reviewing files that changed from the base of the PR and between 5ca721f and a6289bc.

📒 Files selected for processing (45)
  • .changeset/famous-owls-battle.md
  • docs/eslint/stable-query-client.md
  • docs/framework/angular/guides/paginated-queries.md
  • docs/framework/angular/guides/query-options.md
  • docs/framework/angular/typescript.md
  • docs/framework/react/guides/advanced-ssr.md
  • docs/framework/react/guides/initial-query-data.md
  • docs/framework/react/guides/migrating-to-v5.md
  • docs/framework/react/guides/prefetching.md
  • docs/framework/react/guides/query-options.md
  • docs/framework/react/guides/ssr.md
  • docs/framework/react/reference/infiniteQueryOptions.md
  • docs/framework/react/reference/queryOptions.md
  • docs/framework/react/reference/usePrefetchInfiniteQuery.md
  • docs/framework/react/reference/usePrefetchQuery.md
  • docs/framework/react/typescript.md
  • docs/framework/solid/guides/prefetching.md
  • docs/framework/solid/guides/query-options.md
  • docs/framework/solid/typescript.md
  • docs/framework/svelte/ssr.md
  • docs/framework/vue/guides/prefetching.md
  • docs/framework/vue/guides/ssr.md
  • docs/reference/QueryClient.md
  • packages/angular-query-experimental/src/__tests__/infinite-query-options.test-d.ts
  • packages/angular-query-experimental/src/__tests__/query-options.test-d.ts
  • packages/preact-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/preact-query/src/__tests__/queryOptions.test-d.tsx
  • packages/preact-query/src/__tests__/useInfiniteQuery.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/react-query/src/__tests__/queryOptions.test-d.tsx
  • packages/react-query/src/__tests__/useInfiniteQuery.test-d.tsx
  • packages/react-query/src/__tests__/useQuery.promise.test.tsx
  • packages/solid-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/solid-query/src/__tests__/queryOptions.test-d.tsx
  • packages/svelte-query/tests/infiniteQueryOptions.test-d.ts
  • packages/svelte-query/tests/queryOptions.test-d.ts
  • packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts
  • packages/vue-query/src/__tests__/queryClient.test-d.ts
  • packages/vue-query/src/__tests__/queryClient.test.ts
  • packages/vue-query/src/__tests__/queryOptions.test-d.ts
  • packages/vue-query/src/queryClient.ts

Comment on lines +55 to +87
### Imperative QueryClient methods

These methods are deprecated as of Tanstack Query `INSERT_FUTURE_V5_MINOR` and will be removed in v6.

If you are coming from v4 or earlier:

```tsx
queryClient.fetchQuery(key, fn, options) // [!code --]
queryClient.query({ queryKey: key, queryFn: fn, ...options }) // [!code ++]
queryClient.fetchInfiniteQuery(key, fn, options) // [!code --]
queryClient.infiniteQuery({
queryKey: key,
queryFn: fn,
...options,
}) // [!code ++]

queryClient.prefetchQuery(key, fn, options) // [!code --]
queryClient.query({ queryKey: key, queryFn: fn, ...options }).catch(noop) // [!code ++]

queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --]
queryClient
.infiniteQuery({ queryKey: key, queryFn: fn, ...options })
.catch(noop) // [!code ++]

queryClient.ensureQueryData(key, options) // [!code --]
queryClient.query({ queryKey: key, ...options, staleTime: 'static' }) // [!code ++]

queryClient.ensureInfiniteQueryData(key, options) // [!code --]
queryClient.infiniteQuery({ queryKey: key, ...options, staleTime: 'static' }) // [!code ++]
```

If you are updating older v5 code, It will be the same as the above except for keeping the single options object

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Placeholder version number needs to be filled in.

Line 57 contains INSERT_FUTURE_V5_MINOR which should be replaced with the actual version number before merging.

Additionally, the migration examples are comprehensive and clearly show:

  • fetchQueryquery
  • prefetchQueryquery(...).catch(noop)
  • ensureQueryDataquery({ ..., staleTime: 'static' })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/migrating-to-v5.md` around lines 55 - 87, Replace
the placeholder token INSERT_FUTURE_V5_MINOR in the sentence "deprecated as of
Tanstack Query INSERT_FUTURE_V5_MINOR" with the actual release version string
you are targeting (e.g., "v5.<minor>" or the exact minor version being
released); ensure the final sentence reads something like "deprecated as of
Tanstack Query v5.X" and leave the migration examples (fetchQuery → query,
prefetchQuery → query(...).catch(noop), ensureQueryData → query({ ...,
staleTime: 'static' }), etc.) unchanged.

queries: [groupOptions(1), groupOptions(2)],
})
queryClient.prefetchQuery(groupOptions(23))
queryClient.query(groupOptions(23))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find bare queryClient.query(...) calls in docs that don't await/catch on the same line
rg -nP '^\s*queryClient\.query\([^)]*\)\s*$' docs/framework --iglob '*.md'

Repository: TanStack/query

Length of output: 40


🏁 Script executed:

# First, view the actual file content around line 28
head -40 docs/framework/react/guides/query-options.md | tail -20

Repository: TanStack/query

Length of output: 669


🏁 Script executed:

# Better search for bare queryClient.query calls (allowing nested parens)
rg -n 'queryClient\.query\(' docs/framework --iglob '*.md' -A 2

Repository: TanStack/query

Length of output: 7614


Add error handling to prevent unhandled promise rejections in this example.

The bare call queryClient.query(groupOptions(23)) returns a rejected Promise if the query fails. Users copying this documentation snippet may encounter unhandled rejections. The codebase consistently uses .catch(noop) for fire-and-forget patterns elsewhere.

Suggested fix
-queryClient.query(groupOptions(23))
+queryClient.query(groupOptions(23)).catch(() => {})

Note: This pattern appears in at least 3 other documentation examples (react/typescript.md:216, solid/typescript.md:190, solid/guides/query-options.md:35) and should be addressed consistently.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
queryClient.query(groupOptions(23))
queryClient.query(groupOptions(23)).catch(() => {})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/query-options.md` at line 28, The example uses
queryClient.query(groupOptions(23)) which can return a rejected Promise and
cause unhandled rejections; update the snippet to perform the call as a
fire-and-forget with error swallowing (e.g.,
queryClient.query(groupOptions(23)).catch(noop)) so failures are caught, and
apply the same change to the other occurrences of the pattern (references:
queryClient.query, groupOptions, .catch(noop)).

@DogPawHat
Copy link
Copy Markdown
Contributor Author

@coderabbitai What issues are left from the last review?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get all review comments on the PR
gh api repos/TanStack/query/pulls/9835/comments \
  --paginate \
  --jq '.[] | select(.user.login == "coderabbitai[bot]") | {id: .id, path: .path, line: .line, body: .body[:300], created_at: .created_at}' \
  2>/dev/null | head -200

echo "---REVIEWS---"
# Get pull request reviews
gh api repos/TanStack/query/pulls/9835/reviews \
  --paginate \
  --jq '.[] | select(.user.login == "coderabbitai[bot]") | {id: .id, state: .state, submitted_at: .submitted_at, body: .body[:500]}' \
  2>/dev/null | head -200

Length of output: 23867


@DogPawHat Here's a consolidated summary of everything still open from all reviews, grouped by severity:


🔴 Critical / Major

  1. packages/query-core/src/queryClient.ts — Null cache check bug
    query.state.data == null rejects when a valid null is cached. Only === undefined should be treated as "no cached data".

  2. docs/framework/angular/typescript.md Line 224 — Inaccurate runtime behavior note
    The docs say fetchQuery/prefetchQuery ignore select/enabled at runtime, but in this PR they delegate to query, so that statement is now misleading.

  3. docs/framework/svelte/ssr.md Line 10 — SSR silently skips preloading
    When enabled: browser is false on the server, queryClient.query(...) rejects and .catch(noop) swallows it, contradicting the surrounding guidance that the cache is populated server-side.

  4. docs/framework/solid/guides/prefetching.md.catch(noop) on awaited critical data
    The router loader example awaits queryClient.query(...).catch(noop), silently dropping errors that should propagate to the router error boundary.

  5. docs/framework/vue/guides/ssr.md — Undefined suspense in Nuxt examples
    Both Nuxt examples destructure suspsense (typo) but then call await suspense(), creating an undefined reference error.

  6. packages/vue-query/src/queryClient.ts Line 529 — Misleading deprecation hint
    The @deprecated hint for prefetchInfiniteQuery suggests void queryClient.infiniteQuery(options) as a replacement, but void only discards the return value — it does not suppress unhandled rejections. The hint should include .catch(noop).


🟡 Minor / Nitpick

  1. .changeset/famous-owls-battle.md — Typo: "imperitive""imperative" in the changeset message.

  2. docs/framework/react/guides/migrating-to-v5.md Line 87 — Unfilled placeholder: INSERT_FUTURE_V5_MINOR needs to be replaced with the actual version number before merging.

  3. docs/reference/QueryClient.md Line 67 — Intro sentence still references the old method name; should reference queryClient.query.

  4. docs/reference/QueryClient.md Lines 99, 124 — Broken internal anchors: Links to #queryclientensurequerydata and #queryclientfetchquery point to sections that were removed.

  5. docs/framework/angular/guides/query-options.md Line 41 — noop not imported in the code example.

  6. docs/framework/react/guides/query-options.md Line 28 — Bare queryClient.query(...) call without await or .catch(noop).

  7. docs/framework/solid/guides/prefetching.md — Wording: "inside of the query function""inside the query function".

  8. packages/query-core/src/__tests__/queryClient.test-d.tsx Line 272 — Test title says "enabled true" but the test body sets enabled: false.

  9. packages/vue-query/src/queryClient.ts Lines 275–312 — Duplicate query overload: The second and third overloads are identical; one should be removed.

  10. packages/vue-query/src/queryClient.ts Lines 335–376 — Duplicate infiniteQuery overload: Same duplication issue.

  11. packages/query-core/src/queryClient.tsas any cast in infiniteQuery/fetchInfiniteQuery delegation bypasses type safety.


The most important one to fix before merging is #1 (the null cache check bug), as it would cause valid cached null values to trigger a rejection instead of returning the cached data.


🧠 Learnings used
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.

@DogPawHat
Copy link
Copy Markdown
Contributor Author

@coderabbitai Do another full review please

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

@DogPawHat Sure! Triggering a full review of the PR now.


🧠 Learnings used
Learnt from: sukvvon
Repo: TanStack/query PR: 9892
File: packages/solid-query-persist-client/src/__tests__/PersistQueryClientProvider.test.tsx:331-335
Timestamp: 2025-11-22T09:06:05.219Z
Learning: In TanStack/query test files, when a queryFn contains side effects (e.g., setting flags for test verification), prefer async/await syntax for clarity; when there are no side effects, prefer the .then() pattern for conciseness.

Learnt from: Newbie012
Repo: TanStack/query PR: 10295
File: .changeset/exhaustive-deps-allowlist.md:2-5
Timestamp: 2026-03-19T09:24:23.392Z
Learning: In TanStack/query, breaking behavioral changes to `tanstack/eslint-plugin-query` ESLint rules (e.g., the `exhaustive-deps` rule reporting more granularly) are intentionally versioned as `minor` rather than `major`. The rationale (discussed in https://github.com/TanStack/query/issues/6853#issuecomment-3405204044) is that ESLint rules are opt-in, and escape hatches (such as `allowlist` options) are provided to handle false positives. Do not flag such changeset entries as requiring a major bump.

Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Learnt from: Newbie012
Repo: TanStack/query PR: 10295
File: examples/react/eslint-plugin-demo/package.json:8-16
Timestamp: 2026-03-19T09:24:51.614Z
Learning: In TanStack/query, example packages under `examples/` consistently use semver ranges (e.g., `"^5.x.y"`) for TanStack dependencies such as `tanstack/react-query` and `tanstack/eslint-plugin-query` in their `package.json` files, rather than `workspace:*` refs. Do not suggest changing these to workspace refs on the grounds of consistency.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/framework/solid/guides/prefetching.md (1)

97-106: ⚠️ Potential issue | 🟡 Minor

Missing noop import in code examples.

The examples use .catch(noop) but don't show where noop is imported from. This could confuse readers who try to copy these examples.

Consider adding an import statement or a note explaining that noop is a no-op function (e.g., const noop = () => {}).

Suggested addition at the top of examples using noop
 const queryClient = useQueryClient()
+// noop is a function that does nothing, e.g.: const noop = () => {}
 const articleQuery = useQuery(() => ({

Or add the import if there's a common utility:

import { noop } from '@tanstack/query-core' // or define: const noop = () => {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/solid/guides/prefetching.md` around lines 97 - 106, The code
examples call .catch(noop) but never define or import noop; update the examples
that include queryClient.query(...).catch(noop) and any related functions like
getArticleById to either show a short noop definition (e.g., const noop = () =>
{}) or add a clear import statement (e.g., import { noop } from your utility) so
the snippet is copy-pastable and readers know where noop comes from.
docs/framework/vue/guides/ssr.md (1)

143-160: ⚠️ Potential issue | 🟠 Major

Fix the suspense symbol typo in the Nuxt 2 snippet.

The snippet destructures suspsense on line 143 but calls suspense() on line 160, causing a runtime error.

Suggested fix
-    const { data, refetch, suspsense } = useQuery(
+    const { data, refetch, suspense } = useQuery(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/vue/guides/ssr.md` around lines 143 - 160, The code
destructures "suspsense" from useQuery but later calls "suspense()" causing a
runtime error; update the useQuery destructuring to extract "suspense" (not
"suspsense") so the symbol names match, i.e. in the useQuery call that currently
has const { data, refetch, suspsense } = useQuery(...) rename suspsense to
suspense so the subsequent onServerPrefetch(async () => { await suspense() })
call works correctly.
♻️ Duplicate comments (5)
docs/framework/react/guides/query-options.md (1)

28-28: ⚠️ Potential issue | 🟡 Minor

Add error handling to prevent unhandled promise rejections.

The bare call queryClient.query(groupOptions(23)) can cause unhandled rejections if the query fails. Documentation examples should demonstrate safe patterns for fire-and-forget calls.

Suggested fix
-queryClient.query(groupOptions(23))
+queryClient.query(groupOptions(23)).catch(() => {})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/query-options.md` at line 28, The example uses a
bare call to queryClient.query(groupOptions(23)) which can produce unhandled
promise rejections; update the snippet to handle errors by either awaiting the
call inside an async function with try/catch (wrap
queryClient.query(groupOptions(23)) in a try block and handle/log the error in
catch) or, for fire-and-forget, append a .catch handler (or use void with a
.catch) so any rejection from queryClient.query and groupOptions is handled and
won’t leak an unhandled rejection.
docs/framework/svelte/ssr.md (1)

125-131: ⚠️ Potential issue | 🟠 Major

SSR preloading will fail silently due to enabled: browser defaulting to false on server.

Per the QueryClient.query() implementation (lines 373-380 in queryClient.ts), when enabled resolves to false and no cached data exists, query() rejects with an error. The .catch(noop) swallows this error, but no fetch occurs and nothing is cached.

The documentation claims "this data is already available in the cache" (line 140), but with the current setup, the server-side preload is skipped entirely.

Suggested fix: Override enabled for server-side preloading
   await queryClient
     .query({
       queryKey: ['posts'],
       queryFn: async () => (await fetch('/api/posts')).json(),
+      enabled: true, // Override default to ensure server-side fetch
     })
     .catch(noop)

Also update line 10:

-The recommended way to achieve this is to use the `browser` module from SvelteKit in your `QueryClient` object. This will not disable `queryClient.query()`, which is used in one of the solutions below.
+The recommended way to achieve this is to use the `browser` module from SvelteKit in your `QueryClient` object. Note that `queryClient.query()` respects `enabled`, so you must override it to `true` for server-side preloading.

And update line 140:

-  // This data is cached by query in +page.ts so no fetch actually happens here
+  // This data is cached by query (with enabled: true) in +page.ts so no fetch actually happens here
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/svelte/ssr.md` around lines 125 - 131, The SSR preload is
being skipped because QueryClient.query() sees enabled:false on server and
.catch(noop) hides the rejection; update the query call that uses
queryClient.query({ queryKey: ['posts'], queryFn: async () => (await
fetch('/api/posts')).json() }) to explicitly override enabled to true when
running on the server (so the fetch actually runs and data is cached), and
remove or replace the .catch(noop) swallow so server errors are surfaced or
handled appropriately; locate this in the code that builds the posts preload and
ensure any environment check used to decide enabled (e.g., browser/server env)
is inverted for server preloading.
docs/reference/QueryClient.md (2)

66-67: ⚠️ Potential issue | 🟡 Minor

Update stale method names in section prose.

The section headers/examples use query/infiniteQuery, but the prose still calls them fetchQuery/fetchInfiniteQuery.

Suggested fix
-`fetchQuery` is an asynchronous method that can be used to fetch and cache a query. It will either resolve with the data or throw with the error.
+`query` is an asynchronous method that can be used to fetch and cache a query. It will either resolve with the data or throw with the error.
-`fetchInfiniteQuery` is similar to `fetchQuery` but can be used to fetch and cache an infinite query.
+`infiniteQuery` is similar to `query` but can be used to fetch and cache an infinite query.

Also applies to: 111-112

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/QueryClient.md` around lines 66 - 67, Update the stale method
names in the prose by replacing references to fetchQuery and fetchInfiniteQuery
with the current method names query and infiniteQuery; search for occurrences of
"fetchQuery" and "fetchInfiniteQuery" in the QueryClient.md content (including
the parts around the earlier mention and the similar occurrences noted further
down) and edit the sentences so they mention "query" and "infiniteQuery"
consistently with the section headers and examples.

99-99: ⚠️ Potential issue | 🟡 Minor

Fix broken internal anchors in migration/option references.

These links point to removed fragments and currently break in-page navigation.

Suggested fix
-- If you are migrating from [`queryClient.ensureQueryData`](`#queryclientensurequerydata`), use `staleTime: 'static'` to return cached data when it exists, even after invalidation.
+- If you are migrating from `queryClient.ensureQueryData`, use `staleTime: 'static'` to return cached data when it exists, even after invalidation.
-The options for `fetchInfiniteQuery` are exactly the same as those of [`fetchQuery`](`#queryclientfetchquery`).
+The options for `infiniteQuery` are exactly the same as those of [`query`](`#queryclientquery`).

Also applies to: 124-124

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/QueryClient.md` at line 99, The internal anchor
[`#queryclientensurequerydata`] in the sentence about migrating from
queryClient.ensureQueryData is broken; update the link target to the correct
heading ID or remove the fragment so it points to the top of QueryClient.md (or
to the current heading that documents queryClient.ensureQueryData/migration) and
do the same for the duplicate at the other occurrence. Locate the sentence
mentioning "migrating from [`queryClient.ensureQueryData`]" and replace the
fragment link with the proper slugified heading for the current section (or a
plain link to the page) so in-page navigation works.
docs/framework/react/guides/migrating-to-v5.md (1)

57-57: ⚠️ Potential issue | 🟡 Minor

Replace INSERT_FUTURE_V5_MINOR with the real version before merge.

The migration text still has placeholder tokens in two places.

Also applies to: 522-522

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/react/guides/migrating-to-v5.md` at line 57, The docs contain
a placeholder token `INSERT_FUTURE_V5_MINOR` in the migration text (e.g., the
line "These methods are deprecated as of Tanstack Query
`INSERT_FUTURE_V5_MINOR`") and once more elsewhere; replace both occurrences
with the actual Tanstack Query minor version (e.g., "v5.x.y" or the precise
minor number) before merging so the deprecation notice is accurate.
🧹 Nitpick comments (1)
packages/query-core/src/queryClient.ts (1)

467-473: The as any cast bypasses type safety.

The cast at line 473 is needed because InfiniteQueryExecuteOptions adds initialPageParam and behavior which don't align with QueryExecuteOptions. While this works at runtime, it reduces type safety.

Consider adding a brief comment explaining why the cast is safe:

     options.behavior = infiniteQueryBehavior<
       TQueryFnData,
       TError,
       TQueryFnData,
       TPageParam
     >(options.pages)
+    // Cast is safe: infiniteQuery options are a superset of query options
+    // with behavior already set above
     return this.query(options as any)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/query-core/src/queryClient.ts` around lines 467 - 473, The cast "as
any" on the call to this.query(options as any) weakens type safety; instead add
a brief inline comment above the cast explaining why it's safe (e.g., that
InfiniteQueryExecuteOptions only augments QueryExecuteOptions with
initialPageParam and behavior which are handled by infiniteQueryBehavior and
thus conform at runtime), and keep the existing cast or replace it with a
narrower assertion if you prefer; reference the symbols options.behavior,
infiniteQueryBehavior, InfiniteQueryExecuteOptions and QueryExecuteOptions so
future maintainers understand the reasoning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/famous-owls-battle.md:
- Around line 1-6: Update the changeset to include '@tanstack/solid-query' with
a minor bump so the public API change (adding QueryClient.query() and
QueryClient.infiniteQuery() implemented in '@tanstack/query-core' and
re-exported by package-specific QueryClient wrappers) is reflected; specifically
add a line like "'@tanstack/solid-query': minor" alongside the existing entries
and mention that query() and infiniteQuery() were added to the Solid QueryClient
public API.

In `@docs/framework/angular/typescript.md`:
- Line 218: The example uses .catch(noop) but noop is neither defined nor
imported; update the snippet around queryClient.query(this.queries.post(23)) to
either show the noop definition or import (or replace with an inline empty
handler) so readers know what noop refers to—e.g., add a comment or an import
line for noop, or replace .catch(noop) with .catch(() => {}) and mention the
change near queryClient.query and this.queries.post to keep the example
self-contained.

In `@docs/framework/react/guides/advanced-ssr.md`:
- Around line 119-124: The examples use .catch(noop) but noop isn't defined or
imported, causing ReferenceError; add a noop definition or import at the top of
the guide or before each code block that uses it (e.g., the queryClient.query
example using getPosts). Specifically, define a simple noop constant (or import
noop from the appropriate library) and mention it once near the guide's top or
include it inside each snippet so examples using .catch(noop) will run without
errors.

In `@docs/framework/react/guides/ssr.md`:
- Around line 231-236: The examples call .catch(noop) but never define noop; add
a simple no-op function (e.g., const noop = () => {}) immediately before the
await queryClient.query({ queryKey: ['posts'], queryFn: getPosts }) calls in
both snippets so .catch(noop) is valid and the examples are runnable; update
both occurrences that reference noop and queryClient.query/getPosts accordingly.
- Around line 431-434: The snippet uses an undefined variable userId in the
server-side prefetch call; update the query key to use the existing property on
user (i.e., user.userId) so the queryClient.query call uses a defined value.
Locate the conditional that checks user?.userId and change the queryKey from
['projects', userId] to ['projects', user.userId] while keeping the same queryFn
(getProjectsByUser).

In `@docs/framework/solid/guides/query-options.md`:
- Line 35: The example calling queryClient.query(groupOptions(23)) can produce
unhandled promise rejections; wrap the call in proper error handling by awaiting
it inside a try/catch (or attaching .catch) and log/handle errors appropriately
so failures don’t crash the process. Update the docs example around
queryClient.query and groupOptions to show the try/catch pattern (or promise
.catch) and demonstrate handling/logging the error and returning/falling back as
needed.

In `@docs/framework/solid/typescript.md`:
- Line 190: The fire-and-forget call to queryClient.query(groupOptions()) (and
the variant queryClient.query(groupOptions(23))) lacks rejection handling and
can cause unhandled promise rejections; update the example(s) to append a
rejection handler by changing the call to include .catch(() => {}) (or use the
existing project pattern void queryClient.query(...).catch(noop) if noop is
available) so failures are swallowed safely while keeping the snippet
self-contained; locate the occurrences using the symbols queryClient.query and
groupOptions to apply the change.

In `@docs/framework/vue/guides/prefetching.md`:
- Around line 23-25: The bullets are inconsistent and reference an undefined
helper: change the first bullet to use queryClient.query(...) to match the
examples (e.g., queryClient.query({ queryKey: ['todos'], queryFn: fn, staleTime:
5000 })), replace the reference to noop in the second bullet with an inline
no-op (() => {}) or add an explicit import if you prefer, and correct "eg." to
"e.g." so the three bullets are consistent and self-contained; verify this
touches the usage around queryClient.query and any mention of noop.

In `@docs/framework/vue/guides/ssr.md`:
- Around line 171-187: The markdown block is malformed: restore proper prose and
code-fence separation by removing stray inline fence markers and placing the
Vite SSR example inside a single fenced code block (```js ... ```) while moving
headings/prose outside the code fence; ensure the example uses the exact symbols
shown (viteSSR, QueryClient, VueQueryPlugin, hydrate, dehydrate, and
initialState.vueQueryState) and that the surrounding text explains
serializing/dehydrating on SSR and hydrating in the browser with clear headings
and normal paragraph formatting.

In `@packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx`:
- Around line 79-92: The inline comment incorrectly references useInfiniteQuery;
update or remove it so it correctly reflects this test uses
useSuspenseInfiniteQuery: locate the test that creates options via
infiniteQueryOptions and calls useSuspenseInfiniteQuery, then change the comment
"known issue: type of pageParams is unknown when returned from useInfiniteQuery"
to a correct note (for example: "known: useSuspenseInfiniteQuery returns
strongly-typed page data here" or simply remove the sentence) so the comment
matches the referenced function useSuspenseInfiniteQuery and the test intent.

---

Outside diff comments:
In `@docs/framework/solid/guides/prefetching.md`:
- Around line 97-106: The code examples call .catch(noop) but never define or
import noop; update the examples that include queryClient.query(...).catch(noop)
and any related functions like getArticleById to either show a short noop
definition (e.g., const noop = () => {}) or add a clear import statement (e.g.,
import { noop } from your utility) so the snippet is copy-pastable and readers
know where noop comes from.

In `@docs/framework/vue/guides/ssr.md`:
- Around line 143-160: The code destructures "suspsense" from useQuery but later
calls "suspense()" causing a runtime error; update the useQuery destructuring to
extract "suspense" (not "suspsense") so the symbol names match, i.e. in the
useQuery call that currently has const { data, refetch, suspsense } =
useQuery(...) rename suspsense to suspense so the subsequent
onServerPrefetch(async () => { await suspense() }) call works correctly.

---

Duplicate comments:
In `@docs/framework/react/guides/migrating-to-v5.md`:
- Line 57: The docs contain a placeholder token `INSERT_FUTURE_V5_MINOR` in the
migration text (e.g., the line "These methods are deprecated as of Tanstack
Query `INSERT_FUTURE_V5_MINOR`") and once more elsewhere; replace both
occurrences with the actual Tanstack Query minor version (e.g., "v5.x.y" or the
precise minor number) before merging so the deprecation notice is accurate.

In `@docs/framework/react/guides/query-options.md`:
- Line 28: The example uses a bare call to queryClient.query(groupOptions(23))
which can produce unhandled promise rejections; update the snippet to handle
errors by either awaiting the call inside an async function with try/catch (wrap
queryClient.query(groupOptions(23)) in a try block and handle/log the error in
catch) or, for fire-and-forget, append a .catch handler (or use void with a
.catch) so any rejection from queryClient.query and groupOptions is handled and
won’t leak an unhandled rejection.

In `@docs/framework/svelte/ssr.md`:
- Around line 125-131: The SSR preload is being skipped because
QueryClient.query() sees enabled:false on server and .catch(noop) hides the
rejection; update the query call that uses queryClient.query({ queryKey:
['posts'], queryFn: async () => (await fetch('/api/posts')).json() }) to
explicitly override enabled to true when running on the server (so the fetch
actually runs and data is cached), and remove or replace the .catch(noop)
swallow so server errors are surfaced or handled appropriately; locate this in
the code that builds the posts preload and ensure any environment check used to
decide enabled (e.g., browser/server env) is inverted for server preloading.

In `@docs/reference/QueryClient.md`:
- Around line 66-67: Update the stale method names in the prose by replacing
references to fetchQuery and fetchInfiniteQuery with the current method names
query and infiniteQuery; search for occurrences of "fetchQuery" and
"fetchInfiniteQuery" in the QueryClient.md content (including the parts around
the earlier mention and the similar occurrences noted further down) and edit the
sentences so they mention "query" and "infiniteQuery" consistently with the
section headers and examples.
- Line 99: The internal anchor [`#queryclientensurequerydata`] in the sentence
about migrating from queryClient.ensureQueryData is broken; update the link
target to the correct heading ID or remove the fragment so it points to the top
of QueryClient.md (or to the current heading that documents
queryClient.ensureQueryData/migration) and do the same for the duplicate at the
other occurrence. Locate the sentence mentioning "migrating from
[`queryClient.ensureQueryData`]" and replace the fragment link with the proper
slugified heading for the current section (or a plain link to the page) so
in-page navigation works.

---

Nitpick comments:
In `@packages/query-core/src/queryClient.ts`:
- Around line 467-473: The cast "as any" on the call to this.query(options as
any) weakens type safety; instead add a brief inline comment above the cast
explaining why it's safe (e.g., that InfiniteQueryExecuteOptions only augments
QueryExecuteOptions with initialPageParam and behavior which are handled by
infiniteQueryBehavior and thus conform at runtime), and keep the existing cast
or replace it with a narrower assertion if you prefer; reference the symbols
options.behavior, infiniteQueryBehavior, InfiniteQueryExecuteOptions and
QueryExecuteOptions so future maintainers understand the reasoning.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e1203e5c-469c-4f91-9668-1c9f233ae59e

📥 Commits

Reviewing files that changed from the base of the PR and between 3a993e6 and 6abcd30.

📒 Files selected for processing (45)
  • .changeset/famous-owls-battle.md
  • docs/eslint/stable-query-client.md
  • docs/framework/angular/guides/paginated-queries.md
  • docs/framework/angular/guides/query-options.md
  • docs/framework/angular/typescript.md
  • docs/framework/react/guides/advanced-ssr.md
  • docs/framework/react/guides/initial-query-data.md
  • docs/framework/react/guides/migrating-to-v5.md
  • docs/framework/react/guides/prefetching.md
  • docs/framework/react/guides/query-options.md
  • docs/framework/react/guides/ssr.md
  • docs/framework/react/reference/infiniteQueryOptions.md
  • docs/framework/react/reference/queryOptions.md
  • docs/framework/react/reference/usePrefetchInfiniteQuery.md
  • docs/framework/react/reference/usePrefetchQuery.md
  • docs/framework/react/typescript.md
  • docs/framework/solid/guides/prefetching.md
  • docs/framework/solid/guides/query-options.md
  • docs/framework/solid/typescript.md
  • docs/framework/svelte/ssr.md
  • docs/framework/vue/guides/prefetching.md
  • docs/framework/vue/guides/ssr.md
  • docs/reference/QueryClient.md
  • packages/angular-query-experimental/src/__tests__/infinite-query-options.test-d.ts
  • packages/angular-query-experimental/src/__tests__/query-options.test-d.ts
  • packages/preact-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/preact-query/src/__tests__/queryOptions.test-d.tsx
  • packages/preact-query/src/__tests__/useInfiniteQuery.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test-d.tsx
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/queryClient.ts
  • packages/query-core/src/types.ts
  • packages/react-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/react-query/src/__tests__/queryOptions.test-d.tsx
  • packages/react-query/src/__tests__/useInfiniteQuery.test-d.tsx
  • packages/react-query/src/__tests__/useQuery.promise.test.tsx
  • packages/solid-query/src/__tests__/infiniteQueryOptions.test-d.tsx
  • packages/solid-query/src/__tests__/queryOptions.test-d.tsx
  • packages/svelte-query/tests/infiniteQueryOptions.test-d.ts
  • packages/svelte-query/tests/queryOptions.test-d.ts
  • packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts
  • packages/vue-query/src/__tests__/queryClient.test-d.ts
  • packages/vue-query/src/__tests__/queryClient.test.ts
  • packages/vue-query/src/__tests__/queryOptions.test-d.ts
  • packages/vue-query/src/queryClient.ts

Comment on lines +23 to +25
- If a `staleTime` is passed eg. `query({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
- If you want to await while swallowing errors, use `await queryClient.query(options).catch(noop)`
- If you want to always return cached data when it exists, even after invalidation, use `staleTime: 'static'`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n docs/framework/vue/guides/prefetching.md | head -50

Repository: TanStack/query

Length of output: 2667


🏁 Script executed:

rg -i "noop" --type ts --type tsx --type md docs/

Repository: TanStack/query

Length of output: 85


🏁 Script executed:

rg "noop" docs/ --type markdown

Repository: TanStack/query

Length of output: 4223


🏁 Script executed:

cat docs/framework/vue/guides/prefetching.md

Repository: TanStack/query

Length of output: 2324


🏁 Script executed:

rg "noop" --type md docs/framework/vue/

Repository: TanStack/query

Length of output: 197


🏁 Script executed:

find . -name "package.json" -path "*/vue-query/*" -exec cat {} \;

Repository: TanStack/query

Length of output: 3159


🏁 Script executed:

cat packages/vue-query/src/index.ts

Repository: TanStack/query

Length of output: 1510


🏁 Script executed:

rg "export.*noop" packages/query-core/

Repository: TanStack/query

Length of output: 245


🏁 Script executed:

head -100 docs/framework/vue/guides/prefetching.md | grep -i "import"

Repository: TanStack/query

Length of output: 40


🏁 Script executed:

cat docs/framework/react/guides/prefetching.md | head -80

Repository: TanStack/query

Length of output: 3596


Make bullet points consistent with examples and add missing import context.

Line 23 uses query(...) instead of queryClient.query(...) (inconsistent with the example above). Line 24 references noop without import or explanation. Consider using () => {} to avoid the need for an additional import, and correct "eg." to "e.g."

Suggested fix
-- If a `staleTime` is passed eg. `query({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
-- If you want to await while swallowing errors, use `await queryClient.query(options).catch(noop)`
+- If a `staleTime` is passed e.g. `queryClient.query({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
+- If you want to await while swallowing errors, use `await queryClient.query(options).catch(() => {})`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- If a `staleTime` is passed eg. `query({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
- If you want to await while swallowing errors, use `await queryClient.query(options).catch(noop)`
- If you want to always return cached data when it exists, even after invalidation, use `staleTime: 'static'`
- If a `staleTime` is passed e.g. `queryClient.query({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
- If you want to await while swallowing errors, use `await queryClient.query(options).catch(() => {})`
- If you want to always return cached data when it exists, even after invalidation, use `staleTime: 'static'`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/vue/guides/prefetching.md` around lines 23 - 25, The bullets
are inconsistent and reference an undefined helper: change the first bullet to
use queryClient.query(...) to match the examples (e.g., queryClient.query({
queryKey: ['todos'], queryFn: fn, staleTime: 5000 })), replace the reference to
noop in the second bullet with an inline no-op (() => {}) or add an explicit
import if you prefer, and correct "eg." to "e.g." so the three bullets are
consistent and self-contained; verify this touches the usage around
queryClient.query and any mention of noop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants