From 8625df7283d9b7445f434ca7068bbe1c2abf82be Mon Sep 17 00:00:00 2001 From: semimikoh Date: Mon, 6 Apr 2026 15:50:15 +0900 Subject: [PATCH 1/2] fix(query-core): use explicit undefined check for timer IDs Custom TimeoutProvider implementations may return 0 as a valid timer ID (e.g. a counter-based provider), but the existing truthy checks treated 0 as "no timer" and skipped clearTimeout/clearInterval. This left stale timers running, causing unexpected refetches and GC leaks. Compare against undefined instead, matching the optional `?: ManagedTimerId` field types. Fixes #10395 --- packages/query-core/src/queryObserver.ts | 4 ++-- packages/query-core/src/removable.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/query-core/src/queryObserver.ts b/packages/query-core/src/queryObserver.ts index a290c700b58..fa950bcfff3 100644 --- a/packages/query-core/src/queryObserver.ts +++ b/packages/query-core/src/queryObserver.ts @@ -417,14 +417,14 @@ export class QueryObserver< } #clearStaleTimeout(): void { - if (this.#staleTimeoutId) { + if (this.#staleTimeoutId !== undefined) { timeoutManager.clearTimeout(this.#staleTimeoutId) this.#staleTimeoutId = undefined } } #clearRefetchInterval(): void { - if (this.#refetchIntervalId) { + if (this.#refetchIntervalId !== undefined) { timeoutManager.clearInterval(this.#refetchIntervalId) this.#refetchIntervalId = undefined } diff --git a/packages/query-core/src/removable.ts b/packages/query-core/src/removable.ts index 68545f74383..62e524219ca 100644 --- a/packages/query-core/src/removable.ts +++ b/packages/query-core/src/removable.ts @@ -30,7 +30,7 @@ export abstract class Removable { } protected clearGcTimeout() { - if (this.#gcTimeout) { + if (this.#gcTimeout !== undefined) { timeoutManager.clearTimeout(this.#gcTimeout) this.#gcTimeout = undefined } From cb754755139c8308a3c437e90e051fa0cc360754 Mon Sep 17 00:00:00 2001 From: semimikoh Date: Mon, 6 Apr 2026 15:54:50 +0900 Subject: [PATCH 2/2] chore: add changeset for #10395 --- .changeset/fix-timer-id-zero-falsy-check.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-timer-id-zero-falsy-check.md diff --git a/.changeset/fix-timer-id-zero-falsy-check.md b/.changeset/fix-timer-id-zero-falsy-check.md new file mode 100644 index 00000000000..7bec3cdab1c --- /dev/null +++ b/.changeset/fix-timer-id-zero-falsy-check.md @@ -0,0 +1,5 @@ +--- +'@tanstack/query-core': patch +--- + +fix(query-core): use explicit `undefined` check for timer IDs so that custom `TimeoutProvider`s returning `0` as a valid timer ID are properly cleared