vitest-dev/vitest · error · FilesNotFoundError
VITEST_FILES_NOT_FOUND
VITEST_FILES_NOT_FOUND
Error message
No test files found
What it means
FilesNotFoundError (errors.ts, code VITEST_FILES_NOT_FOUND) is thrown at core.ts:868 when specifications.length === 0 after include/exclude glob resolution. It is suppressed in watch mode combined with --changed/--related so a transient empty state doesn't kill the watcher. Any other time, vitest treats zero matched test files as a hard failure so misconfigurations aren't silently green.
Source
Thrown at packages/vitest/src/node/core.ts:868
specifications = specifications.filter(({ testModule }) => {
return !testModule || testModule.task.mode !== 'skip'
})
}
// if run with --changed, don't exit if no tests are found
if (!specifications.length) {
await this._traces.$('vitest.test_run', async () => {
await this._testRun.start([])
await this.coverageProvider?.onTestRunStart?.()
const coverage = await this.coverageProvider?.generateCoverage?.({ allTestsRun: true })
await this._testRun.end([], [], coverage)
// Report coverage for uncovered files
await this.reportCoverage(coverage, true)
})
if (!this.config.watch || !(this.config.changed || this.config.related?.length)) {
throw new FilesNotFoundError()
}
}
let testModules: TestRunResult = {
testModules: [],
unhandledErrors: [],
}
if (specifications.length) {
// populate once, update cache on watch
await this.cache.stats.populateStats(this.config.root, specifications)
testModules = await this.runFiles(specifications, true)
}
if (this.config.watch) {
await this.report('onWatcherStart')
}View on GitHub (pinned to d568f8ce37)
Solutions
- Check test.include / test.exclude glob patterns and the --dir / cwd you run from.
- Verify matching test files exist with the expected extension (.test.ts, .spec.js, etc.).
- Pass --passWithNoTests (or set passWithNoTests: true) if an empty run is intentional.
- In watch mode, use --changed/--related to allow empty runs without error.
Example fix
// before
test: { include: ['src/**/*.test.ts'] } // tests live in tests/
// after
test: { include: ['{src,tests}/**/*.test.ts'] } Defensive patterns
Strategy: validation
Validate before calling
const { glob } = await import('tinyglobby')
const matches = await glob(testInclude, { cwd: root, absolute: false })
if (matches.length === 0 && !passWithNoTests) {
throw new Error('Globs match no files; check test.include')
} Type guard
function hasTestFiles(files: string[]): boolean {
return files.length > 0
} Try / catch
try { await vitest.runFiles(specs) }
catch (e) {
if (e?.code === 'VITEST_FILES_NOT_FOUND' && options.allowEmpty) return { empty: true }
throw e
} Prevention
- Sanity-check that include globs match files before running in CI.
- Set passWithNoTests: true when empty runs are acceptable.
- Run vitest from the repo root or pass --dir explicitly.
When it happens
Trigger: include/exclude globs match zero files; CLI --include/--exclude override strips everything; running from a directory with no matching test files; project test.include empty or wrong root.
Common situations: Wrong cwd; misconfigured include glob; test files renamed/removed; monorepo filter that excludes all packages.
Related errors
- The projects glob matched a file "${relative(parentConfig.ro
- You've enabled headless mode for "preview" provider but it d
- vitest/browser can be imported only inside the Browser Mode.
- ${name}Browser name is required. Please, set `test.browser.i
- Browser Mode requires the "provider" to always be specified.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/8650131dd6757c04.json.
Report an issue: GitHub.