Skip to content

fix(solid-query): untrack the client read in useMutation's cache subscription - #11324

Open
brenelz wants to merge 1 commit into
TanStack:solid-query-v6-prefrom
brenelz:fix/solid-query-mutation-untracked-client
Open

fix(solid-query): untrack the client read in useMutation's cache subscription#11324
brenelz wants to merge 1 commit into
TanStack:solid-query-v6-prefrom
brenelz:fix/solid-query-mutation-untracked-client

Conversation

@brenelz

@brenelz brenelz commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Problem

Any component that calls useMutation triggers Solid's STRICT_READ_UNTRACKED dev diagnostic on mount:

[STRICT_READ_UNTRACKED] Reactive value read directly in <Page> will not update. Move it into a tracking scope (JSX, a memo, or an effect's compute function).

The hook sets up its mutation-cache subscription in the component body with a bare client() read — client is a createMemo, so this is a reactive read outside any tracking scope.

Fix

Wrap the read in untrack, matching how useBaseQuery guards the same body-scope read (untrack(client)). The subscription is intentionally a one-time setup, so a snapshot read is the correct semantics.

The other cache-reading hooks (useIsMutating, useMutationState, useIsFetching) are unaffected: createCacheAggregate already wraps their subscribe/read callbacks in untrack internally.

Test

Added a regression test that renders a bare useMutation component and asserts no STRICT_READ_UNTRACKED warning is emitted. It fails without the fix and passes with it. Full solid-query suite passes (26 files, 345 tests, no type errors).

🤖 Generated with Claude Code

…cription

useMutation subscribes to the mutation cache in the hook body via a bare
client() memo read, which fires Solid's STRICT_READ_UNTRACKED diagnostic
for any component that calls useMutation. Wrap it in untrack, matching
how useBaseQuery guards the same body-scope read.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9870c95e-077b-456c-bd1f-7c3788f31a39

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

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.

@nx-cloud

nx-cloud Bot commented Aug 29, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 34171ce

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

☁️ Nx Cloud last updated this comment at 2026-08-29 03:42:08 UTC

@brenelz

brenelz commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator Author

@ryansolid does this make sense?

@pkg-pr-new

pkg-pr-new Bot commented Aug 29, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-query-experimental

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

@tanstack/eslint-plugin-query

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

@tanstack/lit-query

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

@tanstack/preact-query

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

@tanstack/preact-query-devtools

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

@tanstack/preact-query-persist-client

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

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: 34171ce

@ryansolid

Copy link
Copy Markdown

Good catch — the diagnostic is real, and your read of the semantics (one-time setup snapshot, matching useBaseQuery) is fair. But digging into it, the warning was pointing at something structural: that subscription only does anything between mutate and settle (activeMutation is null otherwise), yet it reads the client at mount and stays attached for the hook's whole life. It also snapshots a different client than mutate builds against, so a QueryClient swap could strand the listener on the old cache.

I put up #11325 which removes the mount-time read instead of untracking it — the subscription becomes per-flight, created next to the build() call on the same client, torn down at settle. Your regression test carries over verbatim (it's what pins the fix), plus a listener-lifecycle test. Closing this in favor of that one, but the find and the test are yours — thanks!

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.

2 participants