Skip to content

debouncer.getAbortSignal() returns null due to maybeExecuteCount increment mismatch #186

@MrPorky

Description

@MrPorky

TanStack Pacer version

0.21.0

Framework/Library version

react

Describe the bug and the steps to reproduce it

When attempting to retrieve the abort signal from the async debouncer using const signal = debouncer.getAbortSignal(), it unexpectedly returns null. This prevents the consumer from properly attaching the abort signal to underlying asynchronous tasks (like fetch requests).

Steps to Reproduce

  1. Initialize an AsyncDebouncer.
  2. Trigger the debounced execution.
  3. Call debouncer.getAbortSignal() within the execution context.
  4. Observe that the returned value is null instead of a valid AbortSignal instance.

Expected Behavior
debouncer.getAbortSignal() should return the active AbortSignal for the current execution so that it can be used to abort pending operations when the debouncer is canceled or re-triggered.

Actual Behavior
debouncer.getAbortSignal() returns null.

Root Cause & Technical Details
The root cause is a state mismatch caused by double-incrementing the maybeExecuteCount property.
Looking at packages/pacer/src/async-debouncer.ts:

  • On line 225, maybeExecuteCount is properly incremented to start the current execution phase.
  • On line 365, the code evaluates maybeExecuteCount + 1 instead of using the current maybeExecuteCount.

Because it checks or assigns an offset value (+ 1) rather than the actual current execution ID, the internal tracking falls out of sync. When getAbortSignal() runs, it fails to match the expected execution ID and consequently returns null.

File Reference:
packages/pacer/src/async-debouncer.ts

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

https://codesandbox.io/p/sandbox/debouncer-getabortsignal-returns-null-due-to-maybeexecutecount-increment-mismatch-dm3n9s

Screenshots or Videos (Optional)

No response

Do you intend to try to help solve this bug with your own PR?

Yes, I am also opening a PR that solves the problem along side this issue

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions