jestjs/jest · error · TypeError
`jest.advanceTimersByTimeAsync()` is not available when usin
Error message
`jest.advanceTimersByTimeAsync()` is not available when using legacy fake timers.
What it means
TypeError thrown by `jest.advanceTimersByTimeAsync()` when the active fake timer implementation is the legacy one (`this.environment.fakeTimers`), not the modern one. The async timer APIs only exist on `@jest/fake-timers`' modern implementation, so calling them under legacy fake timers is unsupported.
Source
Thrown at packages/jest-runtime/src/internals/JestGlobals.ts:303
this.environment.global[logErrorsBeforeRetrySymbol] =
options?.logErrorsBeforeRetry;
this.environment.global[waitBeforeRetrySymbol] = options?.waitBeforeRetry;
this.environment.global[retryImmediatelySymbol] =
options?.retryImmediately;
return jestObject;
};
const jestObject: Jest = {
advanceTimersByTime: msToRun =>
_getFakeTimers().advanceTimersByTime(msToRun),
advanceTimersByTimeAsync: async msToRun => {
const fakeTimers = _getFakeTimers();
if (fakeTimers === this.environment.fakeTimersModern) {
await fakeTimers.advanceTimersByTimeAsync(msToRun);
} else {
throw new TypeError(
'`jest.advanceTimersByTimeAsync()` is not available when using legacy fake timers.',
);
}
},
advanceTimersToNextFrame: () => {
const fakeTimers = _getFakeTimers();
if (fakeTimers === this.environment.fakeTimersModern) {
return fakeTimers.advanceTimersToNextFrame();
}
throw new TypeError(
'`jest.advanceTimersToNextFrame()` is not available when using legacy fake timers.',
);
},
advanceTimersToNextTimer: steps =>
_getFakeTimers().advanceTimersToNextTimer(steps),
advanceTimersToNextTimerAsync: async steps => {
const fakeTimers = _getFakeTimers();View on GitHub (pinned to f49721c78e)
Solutions
- Switch to modern fake timers: `jest.useFakeTimers({ legacyFakeTimers: false })` (or remove the option — modern is default).
- If you must keep legacy timers, use the sync `jest.advanceTimersByTime(ms)` instead of the async variant.
- Remove `fakeTimers: { legacyFakeTimers: true }` from jest.config unless you have a specific reason.
Example fix
// before
jest.useFakeTimers({ legacyFakeTimers: true });
await jest.advanceTimersByTimeAsync(1000); // throws
// after
jest.useFakeTimers(); // modern (default)
await jest.advanceTimersByTimeAsync(1000); Defensive patterns
Strategy: validation
Validate before calling
// Detect which timer backend is active before calling async timer APIs
function isLegacyTimers() {
// legacyFakeTimers is set via config or useFakeTimers; track it yourself:
return Boolean(globalThis.__LEGACY_FAKE_TIMERS__);
}
if (!isLegacyTimers()) {
await jest.advanceTimersByTimeAsync(1000);
} else {
jest.advanceTimersByTime(1000);
} Prevention
- Default to modern fake timers (omit legacyFakeTimers).
- Centralize timer helper functions so the timer mode is decided in one place.
- Add a lint rule or code-review check rejecting `legacyFakeTimers: true`.
When it happens
Trigger: Calling `jest.advanceTimersByTimeAsync(ms)` after enabling legacy fake timers via `jest.useFakeTimers({ legacyFakeTimers: true })` or having `fakeTimers.legacyFakeTimers: true` in jest config.
Common situations: Inheriting a config with `fakeTimers: { legacyFakeTimers: true }`; explicitly opting into legacy timers for a specific behavior then forgetting and calling an async timer method; upgrading Jest and finding old tests relied on legacy timers.
Related errors
- `jest.advanceTimersToNextTimerAsync()` is not available when
- `jest.runAllTimersAsync()` is not available when using legac
- `jest.runOnlyPendingTimersAsync()` is not available when usi
- `jest.advanceTimersToNextFrame()` is not available when usin
- `jest.getRealSystemTime()` is not available when using legac
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/8a08a123070fa44e.json.
Report an issue: GitHub.