Skip to content
Latchkey

Vitest "ReferenceError: describe is not defined" (globals) in CI

Unlike Jest, Vitest does not inject describe, it, and expect as globals by default. Either import them from vitest in each test, or set globals: true in the config so they are available everywhere.

What this error means

Tests fail with "ReferenceError: describe is not defined" or "expect is not defined", often only in CI where a local IDE config masked the difference.

Vitest
ReferenceError: describe is not defined
 ❯ src/sum.test.ts:1:1
      1| describe('sum', () => {
       | ^

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

globals is not enabled and APIs are not imported

Vitest keeps test APIs off the global scope by default, so a Jest-style test that never imports them fails.

The globals TypeScript types were assumed

The code relied on vitest/globals types being present without actually turning on globals: true at runtime.

How to fix it

Enable globals in the config

  1. Set globals: true under test in the config.
  2. Add vitest/globals to types in tsconfig for editor support.
  3. Re-run so the APIs are injected globally.
vitest.config.ts
export default defineConfig({
  test: { globals: true },
})

Or import the APIs explicitly

Keep globals off and import what each file uses; this is the most portable option.

src/sum.test.ts
import { describe, it, expect } from 'vitest'

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

  • Decide once: globals on, or import in every test.
  • Add vitest/globals to tsconfig types when using globals.
  • Do not assume Jest-style globals carry over to Vitest.

Frequently asked questions

What causes Vitest "ReferenceError: describe is not defined" (globals) in CI?
There are 2 common causes: globals is not enabled and apis are not imported and the globals typescript types were assumed. Vitest keeps test APIs off the global scope by default, so a Jest-style test that never imports them fails.
How do I fix Vitest "ReferenceError: describe is not defined" (globals) in CI?
There are 2 fixes depending on which cause you have: enable globals in the config and or import the apis explicitly. Work through them in order, since the first is the most common.
What does Vitest "ReferenceError: describe is not defined" (globals) in CI actually mean?
Tests fail with "ReferenceError: describe is not defined" or "expect is not defined", often only in CI where a local IDE config masked the difference.
How do I stop Vitest "ReferenceError: describe is not defined" (globals) in CI happening again?
Decide once: globals on, or import in every test. 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