fix(query-core): release mutation retryer after execute() settles - #11220
fix(query-core): release mutation retryer after execute() settles#11220okxint wants to merge 1 commit into
Conversation
Mutation.execute() left #retryer set after the mutation settled. The retryer's resolved promise kept the raw mutation result in memory for the mutation's entire lifetime — a second copy alongside the structurally-shared state.data. The same bug existed in Query.fetch() and was fixed in TanStack#11163. The fix mirrors that change exactly: - Capture the retryer in a local variable before the try block - In the finally, null #retryer when it still points to this retryer (the identity check is safe against a re-entrant execute() call installing a fresh retryer from a cache onSuccess callback) - Expose `get promise()` on Mutation to match Query, enabling a parallel regression test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan includes up to 10 reviews per rolling hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesMutation retryer cleanup
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change releases mutation retryer state after execution settles while preserving re-entrant execution behavior; no actionable merge-blocking risk remains beyond normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary
Mutation.execute()leaves#retryerset after the mutation settles. The retryer's resolved promise keeps the raw mutation result in memory for the mutation's entire lifetime — a second copy alongside the structurally-sharedstate.data, and persisting even after the mutation is removed from the cache.This is the direct parallel to the
Query.fetch()memory leak fixed in #11163. The fix is identical in structure.Closes #11216
Root cause
Fix
The identity guard is the same as in
query.ts— it prevents a re-entrantexecute()call (e.g. from aMutationCache.onSuccesscallback) from having its fresh retryer cleared by the outerfinally.Changes
mutation.ts: apply the same 3-line fix asquery.tsline 593-595mutation.ts: addget promise()to matchQuery's public API, enabling a parallel regression testmutations.test.tsx: add regression test that verifiesmutation.promiseisundefinedafterexecute()settles (including re-entrant case)All 25 tests pass.
Summary by CodeRabbit
Bug Fixes
New Features