Vitest "No test files found, exiting with code 1" in CI
Vitest scanned for tests and found none matching its include pattern, so it exits non-zero. Usually the glob does not match your filenames, or CI runs from a directory where no tests live.
What this error means
Vitest prints "No test files found, exiting with code 1" and fails the job. Locally you may run one file by name and see it pass, masking that the default glob matches nothing.
No test files found, exiting with code 1
include: **/*.{test,spec}.?(c|m)[jt]s?(x)
exclude: **/node_modules/**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.
# 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
Filenames do not match the include glob
Vitest picks up *.test.*/*.spec.* by default. Files named *.tests.ts or under a non-default folder are ignored.
Wrong working directory or root in CI
If the job runs vitest from the repo root but tests live in a workspace package, the resolved root contains no matching files.
How to fix it
Set an include pattern that matches your files
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: { include: ['src/**/*.{test,spec}.{ts,tsx}'] },
});Run from the right directory
- Confirm CI runs Vitest in the package that holds the tests (
--rootor aworking-directory). - For monorepos, define a Vitest workspace so each package is discovered.
- Pass
--diror an explicit path to scope discovery if needed.
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
- Commit an explicit
includeglob instead of relying on defaults. - Use a Vitest workspace config in monorepos.
- Add a smoke test so an empty run is obviously wrong.