From 060bd435807d3721d22645d541aeb1732444acd4 Mon Sep 17 00:00:00 2001 From: xxziiko Date: Thu, 22 Jan 2026 21:37:41 +0900 Subject: [PATCH 1/2] chore: add changeset for onMutate sync fix --- .changeset/giant-apples-wear.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/giant-apples-wear.md diff --git a/.changeset/giant-apples-wear.md b/.changeset/giant-apples-wear.md new file mode 100644 index 00000000000..93f7c742aff --- /dev/null +++ b/.changeset/giant-apples-wear.md @@ -0,0 +1,5 @@ +--- +'@tanstack/query-core': patch +--- + +Fix: onMutate callback now runs synchronously when mutationCache.config.onMutate is not defined From 1e71dcbfff45a85ccf4c36c46d8dcf4fe1401ad8 Mon Sep 17 00:00:00 2001 From: xxziiko Date: Thu, 22 Jan 2026 21:37:50 +0900 Subject: [PATCH 2/2] fix(query-core): ensure onMutate runs synchronously when cache config is undefined Fixes #8724 --- .../src/__tests__/mutationCache.test.tsx | 24 +++++++++++++++++++ packages/query-core/src/mutation.ts | 12 ++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/query-core/src/__tests__/mutationCache.test.tsx b/packages/query-core/src/__tests__/mutationCache.test.tsx index e52498c64f7..50337b0e840 100644 --- a/packages/query-core/src/__tests__/mutationCache.test.tsx +++ b/packages/query-core/src/__tests__/mutationCache.test.tsx @@ -249,6 +249,30 @@ describe('mutationCache', () => { expect(states).toEqual([1, 2, 3, 4]) }) + + test('options.onMutate should run synchronously when mutationCache.config.onMutate is not defined', () => { + const key = queryKey() + const states: Array = [] + + // No onMutate in cache config + const testCache = new MutationCache({}) + const testClient = new QueryClient({ mutationCache: testCache }) + + executeMutation( + testClient, + { + mutationKey: key, + mutationFn: () => sleep(10).then(() => ({ data: 5 })), + onMutate: () => { + states.push('onMutate') + return 'context' + }, + }, + 'vars', + ) + + expect(states).toEqual(['onMutate']) + }) }) describe('find', () => { diff --git a/packages/query-core/src/mutation.ts b/packages/query-core/src/mutation.ts index cf879c1ad33..2483b563366 100644 --- a/packages/query-core/src/mutation.ts +++ b/packages/query-core/src/mutation.ts @@ -212,11 +212,13 @@ export class Mutation< } else { this.#dispatch({ type: 'pending', variables, isPaused }) // Notify cache callback - await this.#mutationCache.config.onMutate?.( - variables, - this as Mutation, - mutationFnContext, - ) + if (this.#mutationCache.config.onMutate) { + await this.#mutationCache.config.onMutate( + variables, + this as Mutation, + mutationFnContext, + ) + } const context = await this.options.onMutate?.( variables, mutationFnContext,