Skip to content

fix(query-core): handle the rejection of paused refetches in 'refetchQueries' with 'throwOnError' - #12442

Merged
TkDodo merged 4 commits into
TanStack:mainfrom
lazerg:fix/issue-12441-refetch-paused-unhandled
Nov 1, 2026
Merged

TkDodo merged 4 commits into
TanStack:mainfrom
lazerg:fix/issue-12441-refetch-paused-unhandled

Conversation

@lazerg

@lazerg lazerg commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

🎯 Changes

When a query is paused offline, refetchQueries returns Promise.resolve() for it instead of its fetch promise. With throwOnError: true that fetch promise had no .catch, so cancelling the paused fetch later (for example with queryClient.clear()) caused an unhandled CancelledError, even though the caller awaited refetchQueries.

The paused fetch promise now gets the same .catch(noop) as the non-throwOnError case. The returned promise still resolves right away for paused queries.

Fixes #12441

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I have followed the AI contribution policy and fully understand the code in this pull request, including any code generated with AI assistance.

🚀 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

  • Bug Fixes
    • Paused query refetches no longer produce unhandled cancellation errors when the client is cleared. These refetches do not delay the returned promise, and later errors are handled safely, including when throwOnError is enabled. Refetches that were not paused when started retain their existing throwOnError behavior, preventing unexpected rejection events during cancellation.

@changeset-bot

changeset-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 82376d3

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

This PR includes changesets to release 24 packages
Name Type
@tanstack/query-core Patch
@tanstack/angular-query-experimental Patch
@tanstack/lit-query Patch
@tanstack/preact-query Patch
@tanstack/query-async-storage-persister Patch
@tanstack/query-broadcast-client-experimental Patch
@tanstack/query-devtools Patch
@tanstack/query-persist-client-core Patch
@tanstack/query-sync-storage-persister Patch
@tanstack/react-query Patch
@tanstack/solid-query Patch
@tanstack/svelte-query Patch
@tanstack/vue-query Patch
@tanstack/preact-query-devtools Patch
@tanstack/preact-query-persist-client Patch
@tanstack/react-query-devtools Patch
@tanstack/solid-query-devtools Patch
@tanstack/svelte-query-devtools Patch
@tanstack/vue-query-devtools Patch
@tanstack/react-query-persist-client Patch
@tanstack/solid-query-persist-client Patch
@tanstack/svelte-query-persist-client Patch
@tanstack/react-query-next-experimental Patch
@tanstack/eslint-plugin-query 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

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between ba96027 and 82376d3.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 2b45fed and ba96027.

Files selected for processing: 1
  • packages/query-core/src/queryClient.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Walkthrough

refetchQueries handles rejections from initially paused fetches, including when throwOnError is true. Its returned promise resolves without waiting for those fetches. A regression test checks that clearing the client after an offline refetch does not emit an unhandled rejection.

Changes: Paused refetch handling

Layer / File(s) Summary
Handle paused refetch rejections
packages/query-core/src/queryClient.ts, packages/query-core/src/__tests__/queryClient.test.tsx, .changeset/paused-refetch-unhandled-rejection.md
refetchQueries records whether each fetch is paused, handles rejection from paused fetches, and resolves their contribution immediately. The test covers an offline refetch followed by client cleanup. The changeset records the patch.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • TanStack/query#12441: The issue describes the same unhandled rejection after clearing a client with a paused refetch; this change handles that detached rejection.

Suggested reviewers: sukvvon, tkdodo

Merge Risk: Minimal · previous review ba960

The paused-refetch rejection handling and cleanup regression coverage present no identified merge-blocking risk.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the main change: handling rejected paused refetches in refetchQueries when throwOnError is enabled.
Description check Passed The description explains the problem, the implementation, the preserved behavior, the linked issue, checklist completion, testing, and release impact. It includes the required changeset information.
Linked Issues check Passed Issue #12441 requires an observer for a paused fetch rejection while refetchQueries may resolve immediately. QueryClient.refetchQueries now applies promise.catch(noop) when the fetch is initiall…
Out of Scope Changes check Passed The changes contain the targeted queryClient.ts fix, its regression test, and a patch changeset for @tanstack/query-core. These changes support Issue #12441. No unrelated change is shown.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Full details: Linked Issues check

Explanation

Issue #12441 requires an observer for a paused fetch rejection while refetchQueries may resolve immediately. QueryClient.refetchQueries now applies promise.catch(noop) when the fetch is initially paused and still returns Promise.resolve() for that query. The regression test covers offline pause, throwOnError: true, queryClient.clear(), and the absence of an unhandledRejection event.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 2 files.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@nx-cloud

nx-cloud Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 82376d3

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

☁️ Nx Cloud last updated this comment at 2026-11-01 12:49:19 UTC

@pkg-pr-new

pkg-pr-new Bot commented Nov 1, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-query-experimental

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

@tanstack/eslint-plugin-query

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

@tanstack/lit-query

npm i https://pkg.pr.new/@tanstack/lit-query@12442

@tanstack/preact-query

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

@tanstack/preact-query-devtools

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

@tanstack/preact-query-persist-client

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

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: 82376d3

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refetchQueries with throwOnError leaves paused fetch rejection unhandled on client.clear()

2 participants