Skip to content

fix(solid-query): follow queryClient changes in useMutation 🤖🤖🤖 - #11545

Closed
dijedontahiri wants to merge 9 commits into
TanStack:mainfrom
dijedontahiri:fix/solid-usemutation-queryclient-switch
Closed

dijedontahiri wants to merge 9 commits into
TanStack:mainfrom
dijedontahiri:fix/solid-usemutation-queryclient-switch

Conversation

@dijedontahiri

@dijedontahiri dijedontahiri commented Sep 19, 2026

Copy link
Copy Markdown

🎯 Changes

Fixes #11544.

useMutation resolves a reactive custom queryClient accessor, but its MutationObserver was constructed once from the initial client. Switching the accessor therefore left subsequent mutate() calls on the previous client's defaults/cache and kept the exposed result tied to the old observer.

This change swaps to a fresh MutationObserver when the resolved client changes, resets the exposed state to that observer, and makes mutate() always use the current observer.

The review also exposed an important callback-lifecycle edge case: simply unsubscribing the old observer while one of its mutations is pending suppresses that mutation's per-call callbacks, because MutationObserver only delivers them while it still has listeners. The final implementation therefore retains a state-isolated subscription to an outgoing pending observer until it settles, and releases that subscription either on settlement or component cleanup. Results from the retained observer are never written into the new client's state.

Regression coverage now verifies all three behaviors:

  • after switching clients, new mutations use the new client's defaults/cache;
  • an in-flight old-client mutation still delivers its per-call callback after the client switch;
  • the retained callback is not delivered after the component itself unmounts.

Validation

Exact final candidate: 0606ea9da15f4f8fbc761ffb0aca6593729d6b48
Exact base: d346e85f0144eb9b991e6e1665b22f4574de9751

Hosted immutable-head validation: https://github.com/dijedontahiri/query/actions/runs/35428513719

The validation checked out the exact final candidate SHA and verified meaningful negative controls before running the final tree:

  • exact upstream-base useMutation.ts + the final regression file: the queryClient-switch regression fails while the unrelated unmount control passes;
  • original PR candidate 36990befc39232df24b016b204d393f6d412487d + the final regression file: the basic client-switch regression passes, but the new in-flight per-call callback regression fails while the unmount control passes;
  • exact final candidate: all focused regressions pass.

Final-tree checks all passed:

  • pnpm nx run @tanstack/solid-query:test:lib --skip-nx-cache
  • pnpm nx run @tanstack/solid-query:test:types --skip-nx-cache across the repository's configured TypeScript matrix
  • pnpm nx run @tanstack/solid-query:test:eslint --skip-nx-cache
  • pnpm nx run @tanstack/solid-query:build --skip-nx-cache
  • pnpm nx run @tanstack/solid-query:test:build --skip-nx-cache
  • pnpm run generate-docs with no generated diff
  • pnpm run test:pr --base=d346e85f0144eb9b991e6e1665b22f4574de9751 --head=0606ea9da15f4f8fbc761ffb0aca6593729d6b48 --skip-nx-cache --parallel=2
  • Prettier, git diff --check, exact-head verification, and exact three-file contribution-scope audit.

A patch changeset for @tanstack/solid-query is included.

Automated-agent disclosure: this PR was prepared, tested, updated, and submitted through TanStack Query's documented 🤖🤖🤖 automated-agent opt-in route. It does not claim independent human review.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes with the repository's pnpm run test:pr flow and the focused/package checks listed above.
  • I fully understand the code in this pull request, including any code generated with AI assistance. This is an automated-agent submission; the agent verified the root cause, negative controls, final diff, and tests, but does not claim personal human understanding or independent human review.

🚀 Release Impact

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

@coderabbitai

coderabbitai Bot commented Sep 19, 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: Repository: TanStack/query/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a9b17e28-730e-4762-ab61-31cfaf33f206

📥 Commits

Reviewing files that changed from the base of the PR and between a7fbcca and 0606ea9.

📒 Files selected for processing (1)
  • packages/solid-query/src/useMutation.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/solid-query/src/useMutation.ts

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


📝 Walkthrough

Walkthrough

useMutation now follows a reactive QueryClient change, recreates its observer, retains pending callbacks, and releases subscriptions during cleanup. Integration tests cover client switching, in-flight mutations, and unmount behavior.

Changes

Mutation client switching

Layer / File(s) Summary
Observer recreation and pending retention
packages/solid-query/src/useMutation.ts, .changeset/solid-mutation-client-switch.md
useMutation recreates its MutationObserver when the reactive queryClient accessor returns a different client. It retains pending observer subscriptions and releases them during cleanup. The changeset documents a patch release.
Client switch regression coverage
packages/solid-query/src/__tests__/useMutation.queryClient.test.tsx
Tests verify client-specific mutation results and cache counts, pending callback delivery after a client switch, and callback suppression after unmount.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant QueryClientAccessor
  participant useMutation
  participant MutationObserver
  QueryClientAccessor->>useMutation: provide current QueryClient
  useMutation->>MutationObserver: create observer
  QueryClientAccessor->>useMutation: provide changed QueryClient
  useMutation->>MutationObserver: retain pending observer and unsubscribe
  useMutation->>MutationObserver: create observer for changed client
  MutationObserver->>useMutation: update mutation result
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed For #11544, useMutation stores the current MutationObserver and watches the resolved queryClient accessor. On a client change, it retains pending callbacks, unsubscribes the old observer, create…
Out of Scope Changes check ✅ Passed The changes are limited to the useMutation implementation, focused regression tests, and a patch changeset for @tanstack/solid-query. These changes directly support #11544. No unrelated change is …
Title check ✅ Passed The title clearly and concisely describes the main change: updating Solid Query useMutation to follow queryClient changes. The emojis add minor noise but do not obscure the meaning.
Description check ✅ Passed The description is complete and relevant. It explains the motivation, implementation, regression coverage, validation results, checklist status, release impact, and changeset. The unchecked understand…
  • 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.

Copilot review overview

🟡 Changes recommended

Preserve per-call callback execution for in-flight mutations when switching clients.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Updates Solid Query’s useMutation to follow reactive QueryClient changes by replacing its mutation observer.

Changes:

  • Recreates and subscribes to an observer for the current client.
  • Adds client-switching regression tests.
  • Adds a patch changeset.
File Summary
packages/​solid-query/​src/​useMutation.ts Observer lifecycle updated; critical unresolved issue: switching clients can suppress callbacks for in-flight mutations (1 vote).
packages/​solid-query/​src/​__tests__/​useMutation.queryClient.test.tsx Tests client-specific mutation behavior.
.changeset/​solid-mutation-client-switch.md Records the patch release.

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

on(
client,
(nextClient) => {
unsubscribe()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Confirmed and fixed on the current head 0606ea9da15f4f8fbc761ffb0aca6593729d6b48.

The final implementation retains a state-isolated subscription to an outgoing observer only while its mutation is pending. That keeps the per-call callback lifecycle alive without allowing the old observer to update the new client's exposed state; the retained subscription is released when the old mutation settles or when the component unmounts.

I added two focused regressions around this review case. In immutable-head validation, the original PR candidate 36990befc39232df24b016b204d393f6d412487d passes the basic client-switch test but fails should preserve per-call callbacks for an in-flight mutation after switching clients; the final head passes that test plus the unmount cleanup control. The full Solid unit/type/lint/build/publication checks and root test:pr also pass on the exact final head: https://github.com/dijedontahiri/query/actions/runs/35428513719

Automated-agent reply under the PR's 🤖🤖🤖 route.

@TkDodo TkDodo closed this Sep 19, 2026
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.

solid-query: useMutation stays on the previous QueryClient after a reactive client switch 🤖🤖🤖

3 participants