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.
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 loadedDiagnose 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.
# 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; doneCommon 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.
npm dedupe
npm ls vitest # expect a single resolved versionOnly use Vitest APIs under the runner
- Run tests via the
vitestcommand, not by executing a file withnode. - Do not import
vitesttest APIs insideglobalSetup; use its provided context. - Keep
viteandvitestversions 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
TZandLANGin 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 vitestin CI to catch duplicate installs. - Invoke tests through the Vitest CLI, never directly with Node.