vitest-dev/vitest · error · Error

vi.useFakeTimers({ toFake: ["nextTick"] }) is not supported

Error message

vi.useFakeTimers({ toFake: ["nextTick"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.

What it means

The user-facing `vi.useFakeTimers(config)` wrapper checks both the call-time `config.toFake` AND the global `fakeTimers.toFake` from Vitest config; if either includes `'nextTick'` while running inside a child process (`process.send` is set, i.e. the `forks` pool), it throws. This is the public-layer guard that complements the internal `FakeTimers` one, catching nextTick requests originating from global config too.

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 d568f8ce37)

Solutions

  1. Switch the pool to `threads` (`pool: 'threads'` in config or `--pool=threads`).
  2. Remove `'nextTick'` from `fakeTimers.toFake` in config and from any runtime `vi.useFakeTimers({ toFake })` calls.
  3. Scope nextTick mocking to specific tests under the threads pool rather than globally.

Example fix

// before
// vitest.config.ts
export default defineConfig({ test: { pool: 'forks', fakeTimers: { toFake: ['setTimeout', 'nextTick'] } } })
// after
export default defineConfig({ test: { pool: 'threads', fakeTimers: { toFake: ['setTimeout', 'nextTick'] } } })
Defensive patterns

Strategy: validation

Validate before calling

const isChild = typeof process !== 'undefined' && !!process.send
const globalToFake = (vitestConfig.test?.fakeTimers as any)?.toFake ?? []
if (isChild && (config?.toFake ?? globalToFake).includes('nextTick')) {
  throw new Error('use --pool=threads for nextTick faking')
}

Type guard

function canUseNextTickFake(toFake: string[] = []): boolean {
  const isChild = typeof process !== 'undefined' && !!process.send
  return !isChild || !toFake.includes('nextTick')
}

Prevention

When it happens

Trigger: Running under the `forks`/`child_process` pool with `fakeTimers.toFake` containing `'nextTick'` in `vitest.config.ts`, or calling `vi.useFakeTimers({ toFake: ['nextTick'] })` at runtime, while `process.send` exists.

Common situations: A repo-wide `fakeTimers.toFake` config that includes `nextTick` worked on one developer's `threads` setup but breaks in CI using `forks`; or enabling fake timers globally for all tests.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/760541c5bf75225c.json. Report an issue: GitHub.