Skip to content
Latchkey

Vitest "failed to access its internal state" - Duplicate Install

Vitest keeps per-run state in a single module instance. The error means two copies of Vitest were loaded - usually a version mismatch or a duplicate in node_modules - or test APIs were called outside the runner.

What this error means

The run aborts with "Vitest failed to access its internal state. One of the following is possible: ..." It often appears after a dependency bump, or in a monorepo where packages pull different Vitest versions.

vitest
Error: 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" ...
- Two different versions of "vitest" are loaded

Diagnose it: flake, environment, or genuine failure?

Before debugging the assertion, establish whether the test is deterministic. A test that fails only in CI is usually order-dependent, time-dependent, or racing something, and fixing the assertion will not help.

Terminal
# does it fail in isolation?
npx vitest run path/to/file.test.ts

# is it order dependent? run the suite in a random order twice
npx vitest run --sequence.shuffle

# is it a race? run the same file repeatedly
for i in $(seq 1 20); do npx vitest run path/to/file.test.ts || break; done

Common causes

Two copies of Vitest in the tree

A hoisting issue or mismatched versions across workspace packages put two vitest installs in node_modules; the runner loads one and your test imports another.

Vitest used outside its runner

Importing from vitest in a plain Node script, or inside globalSetup, runs without the runner's initialized state and trips the guard.

How to fix it

Dedupe to a single Vitest version

Align versions and flatten duplicates so exactly one copy is installed.

Terminal
npm dedupe
npm ls vitest   # expect a single resolved version

Only use Vitest APIs under the runner

  1. Run tests via the vitest command, not by executing a file with node.
  2. Do not import vitest test APIs inside globalSetup; use its provided context.
  3. Keep vite and vitest versions compatible.

CI-only causes worth ruling out

  • Runners have fewer cores than a laptop, so timing-sensitive tests that pass locally fail under contention.
  • No TTY and a different locale or timezone. Snapshot tests containing formatted dates or numbers are the usual casualty; pin TZ and LANG in the job.
  • Parallel workers sharing a database, a port, or a temp directory. Give each worker its own namespace.
  • Default timeouts calibrated on a fast machine. A cold runner is slower on first execution, especially before any cache warms.

How to prevent it

  • Pin one Vitest version across all workspace packages.
  • Run npm ls vitest in CI to catch duplicate installs.
  • Invoke tests through the Vitest CLI, never directly with Node.

Frequently asked questions

What causes Vitest "failed to access its internal state"?
There are 2 common causes: two copies of vitest in the tree and vitest used outside its runner. A hoisting issue or mismatched versions across workspace packages put two vitest installs in node_modules; the runner loads one and your test imports another.
How do I fix Vitest "failed to access its internal state"?
There are 2 fixes depending on which cause you have: dedupe to a single vitest version and only use vitest apis under the runner. Work through them in order, since the first is the most common.
What does Vitest "failed to access its internal state" actually mean?
The run aborts with "Vitest failed to access its internal state.
How do I stop Vitest "failed to access its internal state" happening again?
Pin one Vitest version across all workspace packages. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card