vitest-dev/vitest · error · Error
Tag name " " is already defined in "test.tags". Tag names…
Error message
Tag name "${tag.name}" is already defined in "test.tags". Tag names must be unique. What it means
Tag names within `test.tags` must be unique. Vitest accumulates names into a `Set` as it iterates and throws as soon as a duplicate `name` is encountered. Uniqueness is required because tags are referenced by name in test selection and filter expressions, where duplicates would be ambiguous.
Solutions
- De-duplicate by name before exporting: `tags = [...new Map(tags.map(t => [t.name, t])).values()]`.
- Move shared tags into a single config layer so they are not redefined per project.
- If two tags genuinely differ, give them distinct names (e.g. `smoke-unit` vs `smoke-e2e`).
Example fix
// before
export default defineConfig({ test: { tags: [
{ name: 'smoke' }, { name: 'smoke', color: 'red' },
] } })
// after
export default defineConfig({ test: { tags: [{ name: 'smoke', color: 'red' }] } }) Defensive patterns
Strategy: validation
Validate before calling
function dedupeTags<T extends { name: string }>(tags: T[]): T[] {
const seen = new Set<string>()
const out: T[] = []
for (const t of tags) {
if (seen.has(t.name)) continue
seen.add(t.name)
out.push(t)
}
return out
}
export default defineConfig({ test: { tags: dedupeTags(rawTags) } }) Prevention
- Centralise tag definitions in one config layer to avoid cross-file duplication.
- Run a dedupe pass when merging tags from presets and project config.
- Use a Map keyed by name as the single source of truth.
When it happens
Trigger: Two entries with the same `name` (`[{name:'smoke'},{name:'smoke'}]`); merging multiple tag sources (config preset + project config) that both define the same tag; case-sensitive duplicates that look distinct but resolve equal.
Common situations: Shared base config and per-project config both listing `smoke`; refactoring tags across packages without de-duplicating; CI matrix injecting tags that already exist.
Related errors
- Each tag defined in "test.tags" must have a "name"…
- Tag name " " is invalid. Tag names cannot contain spaces.
- Tag name " " is invalid. Tag names cannot be a logical…
- Tag name " " is invalid. Tag names cannot contain "!", "*"…
- Tag " ": priority must be a non-negative number.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/3d4f9814e546e7ef.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/node/config/resolveConfig.ts:293
if ('workspace' in resolved) {
throw new Error('The `test.workspace` option was removed in Vitest 4. Please, migrate to `test.projects` instead. See https://vitest.dev/guide/projects for examples.')
}
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)
})View on GitHub (pinned to 1fa9837ec2)