vitest-dev/vitest · error · Error
Tag name " " is invalid. Tag names cannot contain spaces.
Error message
Tag name "${tag.name}" is invalid. Tag names cannot contain spaces. What it means
Tag names cannot contain whitespace (`/\s/`). Vitest uses tag names in CLI filters and boolean tag expressions where spaces would break tokenisation, so any whitespace is rejected with the offending name in the message.
Solutions
- Use a single token: `smoke-test`, `smoke_test`, or `smokeTest`.
- Trim and validate before export: `name: rawName.trim()` and assert `!/\s/.test(name)`.
- Keep a human-readable `description`/`label` field separate from the machine `name` if your config supports it.
Example fix
// before
export default defineConfig({ test: { tags: [{ name: 'smoke test' }] } })
// after
export default defineConfig({ test: { tags: [{ name: 'smoke-test' }] } }) Defensive patterns
Strategy: validation
Validate before calling
function assertNoSpaces(name: string): void {
if (/\s/.test(name)) {
throw new Error(`Tag name "${name}" must not contain whitespace`)
}
}
const clean = rawTags.map(t => ({ ...t, name: t.name.trim() }))
clean.forEach(t => assertNoSpaces(t.name)) Type guard
function isWhitespaceFreeName(name: string): boolean {
return typeof name === 'string' && !/\s/.test(name)
} Prevention
- Use kebab-case or snake_case for machine tag names.
- Trim and validate tag names at config build time.
- Keep human-readable labels in a separate `description` field.
When it happens
Trigger: `{ name: 'smoke test' }`, `{ name: 'flaky\t' }`, `{ name: 'a b' }`, or names with leading/trailing spaces from copy-paste.
Common situations: Pasting human-readable labels as tag names; importing tags from a spreadsheet/CSV that preserved spaces; typos with tabs/newlines.
Related errors
- Tag name " " is invalid. Tag names cannot contain "!", "*"…
- Each tag defined in "test.tags" must have a "name"…
- Tag name " " is already defined in "test.tags". Tag names…
- Tag name " " is invalid. Tag names cannot be a logical…
- Tag " ": priority must be a non-negative number.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/ddece76a943e6160.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/node/config/resolveConfig.ts:296
}
resolved.pool ??= 'forks'
resolved.project = toArray(resolved.project)
resolved.provide ??= {}
// shallow copy tags array to avoid mutating user config
resolved.tags = [...resolved.tags || []]
const definedTags = new Set<string>()
resolved.tags.forEach((tag) => {
if (!tag.name || typeof tag.name !== 'string') {
throw new Error(`Each tag defined in "test.tags" must have a "name" property, received: ${JSON.stringify(tag)}`)
}
if (definedTags.has(tag.name)) {
throw new Error(`Tag name "${tag.name}" is already defined in "test.tags". Tag names must be unique.`)
}
if (/\s/.test(tag.name)) {
throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot contain spaces.`)
}
if (/[!()*|&]/.test(tag.name)) {
throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot contain "!", "*", "&", "|", "(", or ")".`)
}
if (/^\s*(?:and|or|not)\s*$/i.test(tag.name)) {
throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot be a logical operator like "and", "or", "not".`)
}
if (typeof tag.retry === 'object' && typeof tag.retry.condition === 'function') {
throw new TypeError(`Tag "${tag.name}": retry.condition function cannot be used inside a config file. Use a RegExp pattern instead, or define the function in your test file.`)
}
if (tag.priority != null && (typeof tag.priority !== 'number' || tag.priority < 0)) {
throw new TypeError(`Tag "${tag.name}": priority must be a non-negative number.`)
}
definedTags.add(tag.name)
})
resolved.name = typeof options.name === 'string'
? options.nameView on GitHub (pinned to 1fa9837ec2)