vitest-dev/vitest · error · Error
vi.useFakeTimers( ) is not supported in node:child_process…
Error message
vi.useFakeTimers({ toFake: ["nextTick"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required. What it means
Thrown by `vi.useFakeTimers(config)` when running inside a child process (default `forks` pool) and either the passed `config.toFake` or the global `fakeTimers.toFake` config includes `nextTick`. This duplicates the FakeTimers-level guard (error 181) at the public API boundary with a more actionable message directing the user to `--pool=threads`. Mocking `nextTick` in a forked child process deadlocks Node internals.
Solutions
- Run with `--pool=threads` (or set `pool: 'threads'` in config) so nextTick can be mocked safely.
- Remove `nextTick` from `toFake` in both the call and the `fakeTimers` config.
- Mock `queueMicrotask`/`setTimeout` instead, or restructure the test to avoid nextTick-dependent timing.
Example fix
// before
vi.useFakeTimers({ toFake: ['setTimeout', 'nextTick'] })
// after
vi.useFakeTimers({ toFake: ['setTimeout'] })
// or: vitest run --pool=threads Defensive patterns
Strategy: validation
Validate before calling
function useFakeTimersSafe(cfg) {
const includesNextTick = cfg?.toFake?.includes('nextTick')
const child = typeof process !== 'undefined' && !!process.send
if (includesNextTick && child) {
throw new Error('use --pool=threads to mock nextTick')
}
return vi.useFakeTimers(cfg)
} Type guard
function isChildProcess() {
return typeof process !== 'undefined' && !!process.send
} Prevention
- Do not include 'nextTick' in toFake when using the forks pool.
- Keep fakeTimers.toFake free of nextTick in shared config, or pin pool: 'threads'.
- Document the pool choice in CI so contributors know the constraint.
When it happens
Trigger: Calling `vi.useFakeTimers({ toFake: ['nextTick', ...] })` while running with the `forks` pool; setting `fakeTimers: { toFake: ['nextTick'] }` in the Vitest config and running the default (forks) pool; enabling nextTick globally via config and then calling `vi.useFakeTimers()` without overriding `toFake`.
Common situations: Copying a Jest config that mocked nextTick; project-wide `toFake` setting that includes nextTick combined with the default pool; enabling nextTick to flush microtasks in async tests.
Related errors
- process.nextTick cannot be mocked inside child_process
- A function to advance timers was called but the timers APIs…
- Invalid tick mode
- Vitest mocker was not initialized in this environment. vi.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/760541c5bf75225c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/integrations/vi.ts:510
config: state().config.fakeTimers,
}))
const _stubsGlobal = new Map<
string | symbol | number,
PropertyDescriptor | undefined
>()
const _stubsEnv = new Map()
const _envBooleans = ['PROD', 'DEV', 'SSR']
const utils: VitestUtils = {
useFakeTimers(config?: FakeTimersConfig) {
if (isChildProcess()) {
if (
config?.toFake?.includes('nextTick')
|| state().config?.fakeTimers?.toFake?.includes('nextTick')
) {
throw new Error(
'vi.useFakeTimers({ toFake: ["nextTick"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.',
)
}
}
if (config) {
timers().configure({ ...state().config.fakeTimers, ...config })
}
else {
timers().configure(state().config.fakeTimers)
}
timers().useFakeTimers()
return utils
},
isFakeTimers() {
return timers().isFakeTimers()View on GitHub (pinned to 1fa9837ec2)