vitest-dev/vitest · critical · Error

Vitest failed to access its internal state. One of the…

Error message

Vitest failed to access its internal state.

One of the following is possible:
- "vitest" is imported directly without running "vitest" command
- "vitest" is imported inside "globalSetup" (to fix this, use "setupFiles" instead, because "globalSetup" runs in a different context)
- "vitest" is imported inside Vite / Vitest config file
- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues

What it means

Thrown by getWorkerState when globalThis.__vitest_worker__ is unset. That global is injected only into the worker/context that Vitest's own runtime spawns; the error means code is running somewhere Vitest never initialized. The message lists the four common causes and the issue tracker, because nearly all reports are usage mistakes rather than bugs.

Solutions

  1. Move code that imports vitest from `globalSetup` into `setupFiles` (setupFiles run inside the worker where the state exists).
  2. Do not import `vitest` from your Vite/Vitest config file; read config from the passed-in `defineConfig` argument instead.
  3. Run tests via the `vitest` CLI (or the vitest node API), never by executing test files with `node`/`tsx` directly.
  4. If you truly need worker state in a non-worker context, this is unsupported — restructure so the code runs inside a test or setup file.

Example fix

// before — vitest.config.ts globalSetup imports vitest
import { vi } from 'vitest'
export default defineConfig({
  globalSetup: ['./global-setup.ts'], // global-setup.ts does `import { vi } from 'vitest'`
})

// after — move the logic into setupFiles
export default defineConfig({
  setupFiles: ['./setup.ts'], // runs inside the worker; `import { vi } from 'vitest'` is valid here
})
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect you are inside a Vitest worker before importing vitest
function inVitestWorker(): boolean {
  return !!(globalThis as any).__vitest_worker__
}
if (!inVitestWorker()) {
  // do not import 'vitest' here
}

Type guard

function hasWorkerState(g: typeof globalThis): boolean {
  return !!(g as any).__vitest_worker__
}

Try / catch

try {
  const { vi } = await import('vitest')
} catch (e) {
  if (String(e?.message).startsWith('Vitest failed to access its internal state')) {
    // you imported vitest outside a worker; move this code into setupFiles
    console.error('Move vitest imports into setupFiles, not globalSetup or config')
  }
  throw e
}

Prevention

When it happens

Trigger: Importing `vitest` (or anything that calls getWorkerState, e.g. vi, expect from vitest) from: a plain Node script run with `node`; a globalSetup file (which runs in the main process, not a test worker); the Vite/Vitest config file itself; or a context Vitest did not instrument.

Common situations: Putting `import { vi } from 'vitest'` in a globalSetup that sets up test databases; importing vitest inside vitest.config.ts to read config; running a test file directly with `node test.ts` instead of `vitest`; a third-party tool that imports vitest at module-eval time outside a worker.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/utils.ts:21

const NAME_WORKER_STATE = '__vitest_worker__'

export class EnvironmentTeardownError extends Error {
  name = 'EnvironmentTeardownError'
}

export function getWorkerState(): WorkerGlobalState {
  // @ts-expect-error untyped global
  const workerState = globalThis[NAME_WORKER_STATE]
  if (!workerState) {
    const errorMsg
      = 'Vitest failed to access its internal state.'
        + '\n\nOne of the following is possible:'
        + '\n- "vitest" is imported directly without running "vitest" command'
        + '\n- "vitest" is imported inside "globalSetup" (to fix this, use "setupFiles" instead, because "globalSetup" runs in a different context)'
        + '\n- "vitest" is imported inside Vite / Vitest config file'
        + '\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n'
    throw new Error(errorMsg)
  }
  return workerState
}

export function getSafeWorkerState(): WorkerGlobalState | undefined {
  // @ts-expect-error untyped global
  return globalThis[NAME_WORKER_STATE]
}

export function provideWorkerState(context: any, state: WorkerGlobalState): WorkerGlobalState {
  Object.defineProperty(context, NAME_WORKER_STATE, {
    value: state,
    configurable: true,
    writable: true,
    enumerable: false,
  })

  return state

View on GitHub (pinned to 1fa9837ec2)