vitest-dev/vitest · error · Error
Invalid command name
Error message
Invalid command name "${command}". Only alphanumeric characters, $ and _ are allowed. What it means
projectParent iterates config.browser.commands (user-defined commands) and validates each name with the same identifier regex as registerCommand, because those names are emitted as JS identifier keys in the tester context. Invalid names are rejected at parent setup time, before any test runs.
Solutions
- Rename the command key to a valid identifier (camelCase or snake_case).
- Update every browser.commands.<name>() call site to match the new name.
- Lint the config at startup by asserting the regex against each key.
Example fix
// before
export default defineConfig({ test: { browser: { commands: { 'my-cmd': ctx => 1 } } } })
// after
export default defineConfig({ test: { browser: { commands: { myCmd: ctx => 1 } } } }) Defensive patterns
Strategy: validation
Validate before calling
function validateCommandConfig(commands: Record<string, unknown>): string[] {
return Object.keys(commands).filter(k => !/^[a-z_$][\w$]*$/i.test(k))
} Prevention
- Lint config.browser.commands keys at startup.
- Use camelCase or snake_case for command keys.
- Add a CI check that fails the build on invalid command names.
When it happens
Trigger: Defining browser.commands in vitest.config with a hyphenated or otherwise non-identifier key, e.g. commands: { 'my-cmd': (...) => ... }; using a quoted property name that contains a dot or space.
Common situations: Copy-pasting REST route names into browser.commands; naming commands after CLI flags; coming from a framework where hyphenated command names are conventional.
Related errors
- Invalid command name
- All browser instances within a project must use the same…
- "browser.instances" was set in the config, but the array is…
- Each tag defined in "test.tags" must have a "name"…
- Environment " " is not a valid environment. Path " " should…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/650b9e50061a8112.
Report an issue: GitHub.
Appendix: source
Thrown at packages/browser/src/node/projectParent.ts:118
}
// some browsers (looking at you, safari) don't report queries in stack traces
// the next best thing is to try the first id that this file resolves to
const files = moduleGraph.getModulesByFile(resolvedPath)
if (files && files.size) {
return files.values().next().value!.id!
}
return id
},
}
for (const [name, command] of Object.entries(builtinCommands)) {
this.commands[name] ??= command
}
// validate names because they can't be used as identifiers
for (const command in this.config.browser.commands) {
if (!/^[a-z_$][\w$]*$/i.test(command)) {
throw new Error(
`Invalid command name "${command}". Only alphanumeric characters, $ and _ are allowed.`,
)
}
this.commands[command] = this.config.browser.commands[command]
}
this.prefixTesterUrl = `${base || '/'}`
this.prefixOrchestratorUrl = `${base}__vitest_test__/`
this.faviconUrl = `${base}__vitest__/favicon.svg`
this.manifest = (async () => {
return JSON.parse(
await readFile(`${distRoot}/client/.vite/manifest.json`, 'utf8'),
)
})().then(manifest => (this.manifest = manifest))
this.orchestratorHtml = (this.config.browser.ui
? readFile(resolve(uiClientRoot, 'index.html'), 'utf8')View on GitHub (pinned to 1fa9837ec2)