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

  1. Run with `--pool=threads` (or set `pool: 'threads'` in config) so nextTick can be mocked safely.
  2. Remove `nextTick` from `toFake` in both the call and the `fakeTimers` config.
  3. 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

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


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)