Skip to content

fix(query-core): skip pausing cancelled retries - #11537

Open
brennanbutler01 wants to merge 1 commit into
TanStack:mainfrom
brennanbutler01:fix/cancelled-retry-pause
Open

brennanbutler01 wants to merge 1 commit into
TanStack:mainfrom
brennanbutler01:fix/cancelled-retry-pause

Conversation

@brennanbutler01

@brennanbutler01 brennanbutler01 commented Sep 18, 2026

Copy link
Copy Markdown

🎯 Changes

A retry delay can expire after cancelQueries has already settled the fetch. If the client is offline or unfocused, that old continuation still calls onPause, changing the cancelled query from idle to paused. It can also overwrite a replacement fetch's status and prevent an inactive query from being garbage-collected.

Skip pausing once the retryer has settled. Adds deterministic fake-timer regressions for offline/unfocused cancellation, replacement-fetch status, garbage collection, and React with and without Strict Mode.

Reproduced on 5.101.2, stable 5.103.1 source, and main (bb9d313). All six new core/React regression cases failed before the fix. Afterward, 1,601 core assertions and 585 React tests pass. Searches found no matching active fix; #10291 handles initially paused fetches on unmount and #11342 handles silent-cancellation promise results, rather than delayed pause notifications.

✅ 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 fully understand the code in this pull request, including any code generated with AI assistance.

The full cross-framework test:pr run was not performed. Both affected packages passed test:lib, test:types, test:eslint, and test:build through Nx, including dependency builds. The compiler matrix covers TypeScript 5.6, 5.7, 5.8, 5.9, 6.0, and 7.0. Existing lint warnings are in unchanged code. Tested on Node 24.13.0.

Implemented and locally verified with AI assistance. The contributor-understanding checkbox is left for the author's review.

🚀 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

    • Fixed cancelled queries so they no longer pause or restart unexpectedly when a retry delay expires while the app is offline or unfocused.
    • Ensured replacement fetches continue normally after a cancelled retry.
    • Cancelled queries are now cleaned up correctly after their retry delay.
  • Tests

    • Added coverage for cancelled retries across core and React Query behavior, including offline and unfocused states.

Check whether the retryer settled before its delayed continuation can
notify a pause. A cancelled retry must not overwrite a replacement
fetch status or prevent an inactive query from being collected.

Cover offline and unfocused retries, replacement fetches, garbage
collection, and React cancellation with and without Strict Mode.
Copilot AI lite review requested due to automatic review settings September 18, 2026 07:48
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 47ea69fc-c252-4adc-b59a-dbf63c31d457

📥 Commits

Reviewing files that changed from the base of the PR and between bb9d313 and 8f739a7.

📒 Files selected for processing (5)
  • .changeset/cancelled-retry-pause.md
  • packages/query-core/src/__tests__/query.test.tsx
  • packages/query-core/src/__tests__/retryer.test.tsx
  • packages/query-core/src/retryer.ts
  • packages/react-query/src/__tests__/useQuery.test.tsx

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


📝 Walkthrough

Walkthrough

The retryer now skips pausing when cancellation resolves during a retry delay. Query-core and React Query tests cover replacement fetches, garbage collection, retryer callbacks, and fetch status.

Changes

Cancelled retry handling

Layer / File(s) Summary
Retry delay resolution guard
packages/query-core/src/retryer.ts, .changeset/cancelled-retry-pause.md
The retry delay continuation checks isResolved() before pausing. The changeset declares a patch release for @tanstack/query-core.
Cancellation behavior coverage
packages/query-core/src/__tests__/retryer.test.tsx, packages/query-core/src/__tests__/query.test.tsx, packages/react-query/src/__tests__/useQuery.test.tsx
Tests cover cancelled retryers, replacement fetches, garbage collection, and idle fetch status while focus changes.

Priority: ⬇️ Low

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

Change: Bug fix

Suggested reviewers: tkdodo

Merge Risk: ⚪ Minimal · up to 8f739

The cancellation retry-delay fix is covered across core and React scenarios and is ready to merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 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%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 4 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: cancelled retries no longer pause after their retry delay expires.
Description check ✅ Passed The description follows the required template, explains the motivation and implementation, documents testing limitations, and includes a changeset. The unchecked full test:pr and contributor-understan…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 4 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No unresolved review issues were identified.

Pull request overview

Fixes cancelled retry continuations incorrectly pausing settled queries, with core and React regression coverage.

Changes:

  • Skip pause notifications after retryer settlement.
  • Add cancellation, replacement-fetch, garbage-collection, and Strict Mode tests.
  • Add a query-core patch changeset.
File summaries
File Description
packages/react-query/src/__tests__/useQuery.test.tsx Tests React cancellation behavior with and without Strict Mode.
packages/query-core/src/retryer.ts Prevents settled retryers from pausing queries.
packages/query-core/src/__tests__/retryer.test.tsx Tests cancelled retry behavior.
packages/query-core/src/__tests__/query.test.tsx Tests replacement fetches and garbage collection.
.changeset/cancelled-retry-pause.md Documents the patch release.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

3 participants