vitest-dev/vitest · error · Error
The Vitest config does't define any "tags", cannot apply
Error message
The Vitest config does't define any "tags", cannot apply "${tag}" ${prefix} for this test. See: https://vitest.dev/guide/test-tags What it means
Thrown by createNoTagsError when a test (or suite) references a tag but the Vitest config defines zero tags via the `tags` option. Vitest's strict-tags feature (on by default via strictTags) requires every tag used in test files to be declared in the config first, so an empty `tags` array means no tag can be applied. The message is produced from two call sites: validateTags (collection-time, prefix='tag') and resolveTagPattern (CLI filter evaluation, prefix='tag pattern').
Solutions
- Add a `tags` array to your vitest config defining every tag you use, e.g. `defineConfig({ tags: [{ name: 'smoke' }] })`.
- If you intentionally want undeclared tags allowed, set `strictTags: false` in the config.
- Remove the `tags` option from the offending test/suite if tagging was unintended.
- Confirm the tag name in the test exactly matches a `name` in config.tags (case-sensitive).
Example fix
// before
test('auth', { tags: ['smoke'] }, () => {})
// vitest.config.ts — no tags key
// after (vitest.config.ts)
export default defineConfig({
tags: [{ name: 'smoke', description: 'critical-path checks' }],
}) Defensive patterns
Strategy: validation
Validate before calling
// Run before adding a tag to a test/suite
import { getTagsFromConfig } from './test-helpers' // returns the Set of declared tag names
const declared = getTagsFromConfig() // from defineConfig.tags
const tagsToAdd = ['smoke']
const unknown = tagsToAdd.filter(t => !declared.has(t))
if (declared.size === 0 && tagsToAdd.length) {
throw new Error('No tags declared in vitest config; add the `tags` option first.')
} Type guard
function isTagDeclared(declared: ReadonlySet<string>, tag: string): boolean {
return declared.size > 0 && declared.has(tag)
} Prevention
- Centralize the list of tag names as a const and reuse it in both defineConfig.tags and tests.
- Enable strictTags (the default) in CI so undeclared tags fail fast.
- Add an editor lint rule or pre-commit check that greps test files for `{ tags: [...] }` against the declared set.
When it happens
Trigger: A test/suite calls `test('x', { tags: ['smoke'] }, fn)` or `describe('x', () => {}, { tags: ['smoke'] })`, or the CLI `--tag smoke` is passed, while `defineConfig({ tags: [] })` or no `tags` key at all is set. Because strictTags defaults to true (serializeConfig.ts:157), the check always runs unless explicitly disabled.
Common situations: Developers add `{ tags: [...] }` to a test before declaring the tag in vitest.config; teams adopting the tags feature for the first time and forgetting the config half; copying a test from another project that used tags into a project whose config has none.
Related errors
- 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 contain spaces.
- Tag name " " is invalid. Tag names cannot be a logical…
- Tag name " " is invalid. Tag names cannot contain "!", "*"…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/75b4f4a14d4692c8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/runner/utils/tags.ts:39
return tagsFilterPredicate(testTags)
}
export function validateTags(config: SerializedConfig, tags: string[]): void {
if (!config.strictTags) {
return
}
const availableTags = new Set(config.tags.map(tag => tag.name))
for (const tag of tags) {
if (!availableTags.has(tag)) {
throw createNoTagsError(config.tags, tag)
}
}
}
export function createNoTagsError(availableTags: TestTagDefinition[], tag: string, prefix = 'tag'): never {
if (!availableTags.length) {
throw new Error(`The Vitest config does't define any "tags", cannot apply "${tag}" ${prefix} for this test. See: https://vitest.dev/guide/test-tags`)
}
throw new Error(`The ${prefix} "${tag}" is not defined in the configuration. Available tags are:\n${availableTags
.map(t => `- ${t.name}${t.description ? `: ${t.description}` : ''}`)
.join('\n')}`)
}
export function createTagsFilter(tagsExpr: string[], availableTags: TestTagDefinition[]): (testTags: string[]) => boolean {
const matchers = tagsExpr.map(expr => parseTagsExpression(expr, availableTags))
return (testTags: string[]) => {
return matchers.every(matcher => matcher(testTags))
}
}
type TagMatcher = (tags: string[]) => boolean
function parseTagsExpression(expr: string, availableTags: TestTagDefinition[]): TagMatcher {
const tokens = tokenize(expr)
const stream = new TokenStream(tokens, expr)View on GitHub (pinned to 1fa9837ec2)