fix(solid-query): untrack the result read in useMutationState's cache subscription - #11359
fix(solid-query): untrack the result read in useMutationState's cache subscription#11359daviduzumeri wants to merge 1 commit into
Conversation
… subscription MutationCache notifies synchronously, so the subscription callback runs while the computation that called `mutate` is still the active listener. Reading the hook's own result signal there registered it as a dependency of that computation, which `setResult` then immediately invalidated — so calling `mutate` from inside an effect re-ran the effect on every mutation, and an unguarded `mutate` looped. Adds a regression test: an effect that mutates once runs twice before this change and once after.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesMutation state tracking
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change prevents mutation-cache updates from spuriously rerunning Solid computations while preserving existing result behavior, with regression coverage for the reported loop. No actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation 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 2 functions across 2 files. (1 skipped: 1 unsupported.)
✨ 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 |
🎯 Changes
useMutationState's mutation-cache subscription reads the hook's ownresultsignal:MutationCachenotifies synchronously, so when a mutation is started from inside a Solid computation, that callback runs while the computation is still the active listener. Theresult()read therefore registers the signal as a dependency of that computation — andsetResultimmediately invalidates it.The practical effect: calling
mutatefrom inside acreateEffectre-runs the effect on every mutation, and an unguardedmutateloops. It also attaches a spurious dependency to whatever computation happens to be running when any mutation settles, which is hard to attribute when it shows up as a runaway effect cascade in production.The read is now untracked. Behaviour is otherwise identical.
Regression test
Added to
useMutationState.test.tsx: an effect that triggers one mutation, with a guard so a genuine loop still terminates.expected 2 to be 1— the effect re-ranRelationship to #9644
#9644 proposed the same
untrackalongside auseIsMutatingfix. That PR has been open since Sept 2025, last updated June 2026, and is now conflicted; itsuseIsMutatinghalf has since landed separately. This is just the remaining half, rebased onmainwith a test and a changeset. Happy to close it in favour of #9644 if that one is revived.Also related: #10907 (the
enabled: falseSSR hang) was a different symptom of solid-query reading signals from cache callbacks, and is already fixed.✅ Checklist
pnpm run test:pr, or these tests do not apply to this pull request.Scope of what I ran:
vitest runfor@tanstack/solid-query— 247 runtime tests pass (13 files).useQuery.test-d.tsxfails 5 type assertions, but it does so identically on unmodifiedmainwith my changes stashed, so it is pre-existing and unrelated to this change.🚀 Release Impact
Summary by CodeRabbit
Bug Fixes
useMutationStatewhen mutations are initiated within reactive effects.Tests
useMutationState.