vitest-dev/vitest · error · Error
The projects glob matched a file "${relative(parentConfig.ro
Error message
The projects glob matched a file "${relative(parentConfig.root, path)}", but it should also either start with "vitest.config"/"vite.config" or match the pattern "(vitest|vite).*.config.*". What it means
Thrown during project resolution when the `projects` glob in your vitest config matches a filesystem entry that is a plain file but does not look like a Vite/Vitest config file. Vitest validates the file's basename against the regex `/^vite(?:st)?(?:\.[\w-]+)?\.config\./` (defined at resolveProjects.ts:40); only files matching that pattern (e.g. `vitest.config.ts`, `vite.workspace.config.mjs`) are accepted as project configs. Any other matched file aborts resolution because Vitest cannot infer how to load it as a project.
Source
Thrown at packages/vitest/src/node/projects/resolveProjects.ts:1071
const projectsFs = await glob(projectsGlobMatches, globOptions)
projectsFs.forEach((path) => {
// directories are allowed with a glob like `packages/*`
// in this case every directory is treated as a project
if (path.endsWith('/')) {
const configFile = resolveDirectoryConfig(path)
if (configFile) {
projectsConfigFiles.push(configFile)
}
else {
nonConfigProjectDirectories.push(path)
}
}
else {
const name = basename(path)
if (!CONFIG_REGEXP.test(name)) {
throw new Error(
`The projects glob matched a file "${relative(parentConfig.root, path)}", `
+ `but it should also either start with "vitest.config"/"vite.config" `
+ `or match the pattern "(vitest|vite).*.config.*".`,
)
}
projectsConfigFiles.push(path)
}
})
}
const projectConfigFiles = Array.from(new Set(projectsConfigFiles))
return {
projectConfigs: projectsOptions,
nonConfigDirectories: nonConfigProjectDirectories,
configFiles: projectConfigFiles,
}
}View on GitHub (pinned to d568f8ce37)
Solutions
- Change the `projects` glob so it only matches directories (e.g. `packages/*` matched against folders) or config files specifically.
- Rename the matched file to follow the `vitest.config.*` / `vite.config.*` / `vitest.<scope>.config.*` convention.
- Add more specific ignore patterns or narrow the glob to `**/vitest.config.*` to avoid catching unrelated files.
- Delete or relocate the stray non-config file that the glob is matching.
Example fix
// before (vitest.config.ts)
export default defineConfig({
projects: ['packages/*'] // matches packages/shared.js as a file
})
// after
export default defineConfig({
projects: ['packages/*/vitest.config.ts']
}) Defensive patterns
Strategy: validation
Validate before calling
import { glob } from 'tinyglobby'
import { basename } from 'node:path'
const CONFIG_REGEXP = /^vite(?:st)?(?:\.[\w-]+)?\.config\./
const matches = await glob(['packages/*'], { cwd: root, absolute: true, onlyFiles: false, dot: true })
const bad = matches.filter(p => !p.endsWith('/') && !CONFIG_REGEXP.test(basename(p)))
if (bad.length) throw new Error(`Non-config files matched by projects glob: ${bad.join(', ')}`) Type guard
import { basename } from 'node:path'
const CONFIG_REGEXP = /^vite(?:st)?(?:\.[\w-]+)?\.config\./
const isConfigFile = (p: string): boolean => CONFIG_REGEXP.test(basename(p)) Prevention
- Prefer directory-style globs (`packages/*`) so non-config files are skipped via directory config resolution.
- When globbing files directly, restrict to `**/vitest.config.*` / `**/vite.config.*`.
- Run a dry glob of your `projects` value before committing the config.
When it happens
Trigger: Setting `projects: ['packages/*']` where one of the matched entries is a file (not a directory) whose name fails CONFIG_REGEXP, e.g. a `packages/README.md` or a stray `packages/index.js`. Also triggered by a glob that accidentally includes dotfiles or build artifacts like `packages/vitest.rollup.config.js` only if the segment after `vite`/`vitest` contains chars outside `[\w-]`. Directories ending with `/` are handled separately (resolveDirectoryConfig), so only bare-file matches hit this branch.
Common situations: Pointing `projects` at a flat layout where packages are files rather than folders; renaming a config to something non-conventional (e.g. `vitest.conf.ts`); a glob like `**/vitest.*` that also catches non-config files; monorepo migrations that leave behind a file matching the glob but not the naming convention.
Related errors
- VITEST_FILES_NOT_FOUND
- Project name "${name}"${entryFile ? ` from "${entryFile}"` :
- 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
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/9a29aa74b5c37612.json.
Report an issue: GitHub.