vitest-dev/vitest · error · Error

process.nextTick cannot be mocked inside child_process

Error message

process.nextTick cannot be mocked inside child_process

What it means

Raised by `FakeTimers.useFakeTimers()` when Vitest detects it is running inside a Node `child_process` and the user's `toFake` list explicitly includes `nextTick`. Mocking `process.nextTick` inside a child process (the default `forks` pool) breaks Node internals, so Vitest forbids it. The guard runs before installing the sinon fake clock.

Solutions

  1. Remove `nextTick` from the `toFake` array in `vi.useFakeTimers(...)` or in `test.fakeTimers.toFake` config.
  2. Switch the pool to threads: `--pool=threads` (or `pool: 'threads'` in config) if you must mock nextTick.
  3. Mock `queueMicrotask`/`setTimeout` instead, or restructure the test to avoid relying on nextTick scheduling.

Example fix

// before
vi.useFakeTimers({ toFake: ['setTimeout', 'nextTick'] })

// after (forks pool)
vi.useFakeTimers({ toFake: ['setTimeout'] })
// or run with --pool=threads and keep nextTick
Defensive patterns

Strategy: validation

Validate before calling

function safeUseFakeTimers(cfg) {
  if (cfg?.toFake?.includes('nextTick') && isChildProcessLike()) {
    throw new Error('nextTick mocking requires --pool=threads')
  }
  return vi.useFakeTimers(cfg)
}

Type guard

function isChildProcessLike() {
  return typeof process !== 'undefined' && !!process.send // forked child has process.send
}

Prevention

When it happens

Trigger: Setting `fakeTimers.toFake` in config (or calling `vi.useFakeTimers({ toFake: ['nextTick'] })` via the timers API) to include `nextTick` while the active pool is `forks` (child_process). Reached when the FakeTimers class itself is driven directly with a config that includes `nextTick`.

Common situations: Migrating from Jest where nextTick mocking was allowed; copying a `toFake` array from a threads-pool project into a forks-pool project; explicitly enabling `nextTick` to flush microtasks in tests.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/d5337d8dc77e3bff. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/integrations/mock/timers.ts:161

      this._clock.uninstall()
      this._fakingTime = false
    }
  }

  useFakeTimers(): void {
    const fakeDate = this._fakingDate || Date.now()
    if (this._fakingDate) {
      this._clock.uninstall()
      this._fakingDate = null
    }

    if (this._fakingTime) {
      this._clock.uninstall()
    }

    let toFake = this._userConfig?.toFake
    if (isChildProcess() && toFake?.includes('nextTick')) {
      throw new Error(
        'process.nextTick cannot be mocked inside child_process',
      )
    }

    let toNotFake = this._userConfig?.toNotFake
    if (toFake === undefined && toNotFake === undefined) {
      // Do not mock timers internally used by node by default. It can still be mocked through userConfig.
      toFake = (Object.keys(this._fakeTimers.timers) as FakeMethod[])
        .filter(timer => timer !== 'nextTick' && timer !== 'queueMicrotask')
    }
    if (isChildProcess() && toNotFake && !toNotFake.includes('nextTick')) {
      toNotFake = [...toNotFake, 'nextTick']
    }

    this._clock = this._fakeTimers.install({
      now: fakeDate,
      ...this._userConfig,
      ...(toFake && { toFake }),

View on GitHub (pinned to 1fa9837ec2)