Skip to content
Latchkey

Vitest fake timers not advancing (test hangs) in CI

After vi.useFakeTimers(), real timers are replaced with controllable ones. Code that awaits a setTimeout will hang forever unless you advance the fake clock. In CI this shows as a test timing out rather than a clear error.

What this error means

A test using fake timers stalls until it hits the test timeout ("Test timed out in 5000ms"), because nothing advanced the clock so a pending timer never fired.

Vitest
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument.
 ❯ src/debounce.test.ts:9:3

Common causes

Fake timers were enabled but never advanced

A pending setTimeout/setInterval is frozen until you advance the fake clock, so an awaited promise chained to it never settles.

Real timers were not restored between tests

Leaving fake timers on leaks into later tests, which then hang on timers they expected to run for real.

How to fix it

Advance the fake clock

  1. Call vi.advanceTimersByTime(ms) or vi.runAllTimers() to fire pending timers.
  2. Restore real timers in an afterEach so state does not leak.
  3. Re-run so awaited timers resolve promptly.
src/debounce.test.ts
vi.useFakeTimers()
const p = debounced()
vi.advanceTimersByTime(300)
await p
afterEach(() => vi.useRealTimers())

Use runAllTimersAsync for promise-based timers

When timers schedule microtasks, advance them with the async variant so awaited chains complete.

src/debounce.test.ts
await vi.runAllTimersAsync()

How to prevent it

  • Always advance fake timers explicitly in the test.
  • Restore real timers in afterEach.
  • Prefer runAllTimersAsync when timers resolve promises.

Frequently asked questions

What causes "Fake timers never advance"?
A pending setTimeout/setInterval is frozen until you advance the fake clock, so an awaited promise chained to it never settles.
How do I fix Fake timers never advance?
Advance the fake clock

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card