vitest-dev/vitest · error · Error
The file "${relative(parentConfig.root, file)}" must start w
Error message
The file "${relative(parentConfig.root, file)}" must start with "vitest.config"/"vite.config" or match the pattern "(vitest|vite).*.config.*" to be a valid project config. What it means
When a string entry points to an existing file (resolveProjects.ts:991-997), Vitest checks the basename against CONFIG_REGEXP = /^vite(?:st)?(?:\.[\w-]+)?\.config\./, which accepts vitest.config.*, vite.config.*, vitest.<scope>.config.*, vite.<scope>.config.*. Files that don't match (e.g. random.ts, tsconfig.json, package.json) are rejected so config loader doesn't choke on them.
Source
Thrown at packages/vitest/src/node/projects/resolveProjects.ts:993
for (const definition of projectsDefinition) {
if (typeof definition === 'string') {
const stringOption = definition.replace('<rootDir>', parentConfig.root)
// if the string doesn't contain a glob, we can resolve it directly
// ['./vitest.config.js']
if (!isDynamicPattern(stringOption)) {
const file = resolve(parentConfig.root, stringOption)
if (!existsSync(file)) {
throw new Error(`Projects definition references a non-existing file or a directory: ${file}`)
}
const stats = statSync(file)
// user can specify a config file directly
if (stats.isFile()) {
const name = basename(file)
if (!CONFIG_REGEXP.test(name)) {
throw new Error(
`The file "${relative(parentConfig.root, file)}" must start with "vitest.config"/"vite.config" `
+ `or match the pattern "(vitest|vite).*.config.*" to be a valid project config.`,
)
}
projectsConfigFiles.push(file)
}
// user can specify a directory that should be used as a project
else if (stats.isDirectory()) {
const configFile = resolveDirectoryConfig(file)
if (configFile) {
projectsConfigFiles.push(configFile)
}
else {
const directory = file.at(-1) === '/' ? file : `${file}/`
nonConfigProjectDirectories.push(directory)
}
}View on GitHub (pinned to d568f8ce37)
Solutions
- Rename or point to a file matching vitest.config.* / vite.config.* / vitest.<scope>.config.* / vite.<scope>.config.*.
- If you meant a directory, add a trailing slash so it's resolved as a directory project.
- For globs that over-match, constrain the pattern (e.g. 'packages/*/vitest.config.ts').
Example fix
// before
export default defineConfig({ test: { projects: ['./package.json'] } })
// after
export default defineConfig({ test: { projects: ['./vitest.config.ts'] } }) Defensive patterns
Strategy: validation
Validate before calling
const CONFIG_REGEXP = /^vite(?:st)?(?:\.[\w-]+)?\.config\./
for (const def of definitions) {
if (typeof def === 'string' && !def.endsWith('/') && existsSync(resolve(root, def))) {
if (!CONFIG_REGEXP.test(basename(def))) throw new Error(`'${def}' is not a valid config file name`)
}
} Type guard
function isValidConfigName(name: string): boolean {
return /^vite(?:st)?(?:\.[\w-]+)?\.config\./.test(name)
} Prevention
- Follow the vite.config.* / vitest.config.* naming convention.
- Use a trailing slash to reference a directory project.
- Tighten project globs so they only match real config files.
When it happens
Trigger: Listing a non-config file in projects: ['package.json'], ['src/index.ts'], ['random.config.js'] that doesn't start with vite/vitest.config.; pointing at a vite.config file with an unexpected prefix.
Common situations: Confusing a project source file with a config file; pointing projects at a filename that almost matches (e.g. 'viteconfig.ts' missing the dot); a glob that accidentally matches a non-config file.
Related errors
- Project name "${name}" is not unique. All projects should ha
- Project name "${name}"${entryFile ? ` from "${entryFile}"` :
- `resolveOptions` has to be used in a test file
- Invalid command name "${name}". Only alphanumeric characters
- Invalid command name "${command}". Only alphanumeric charact
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/0f5640a129e2471d.json.
Report an issue: GitHub.