vitest-dev/vitest · error · Error
Exact option does not support RegExp expected class names
Error message
Exact option does not support RegExp expected class names
What it means
Thrown by toHaveClass (packages/browser/src/client/tester/expect/toHaveClass.ts:40-43) when the { exact: true } option is combined with one or more RegExp expected class names. Exact mode (lines 45-63) requires the expected class set to equal the received class set by length and content, which is meaningless for a RegExp (a pattern has no fixed length/count), so the combination is rejected as a hard error rather than silently producing a confusing result.
Source
Thrown at packages/browser/src/client/tester/expect/toHaveClass.ts:42
): MatcherResult {
const htmlElement = getElementFromUserInput(actual, toHaveClass, this)
const { expectedClassNames, options } = getExpectedClassNamesAndOptions(params)
const received = splitClassNames(htmlElement.getAttribute('class'))
const expected = expectedClassNames.reduce(
(acc, className) => {
return acc.concat(
typeof className === 'string' || !className
? splitClassNames(className)
: className,
)
},
[] as (string | RegExp)[],
)
const hasRegExp = expected.some(className => className instanceof RegExp)
if (options.exact && hasRegExp) {
throw new Error('Exact option does not support RegExp expected class names')
}
if (options.exact) {
return {
pass: isSubset(expected, received) && expected.length === received.length,
message: () => {
const to = this.isNot ? 'not to' : 'to'
return getMessage(
this,
this.utils.matcherHint(
`${this.isNot ? '.not' : ''}.toHaveClass`,
'element',
this.utils.printExpected(expected.join(' ')),
),
`Expected the element ${to} have EXACTLY defined classes`,
expected.join(' '),
'Received',
received.join(' '),View on GitHub (pinned to d568f8ce37)
Solutions
- Drop exact when using regex: expect(el).toHaveClass(/btn-.*/).
- If you need exactness, convert the regex to literal class names: expect(el).toHaveClass('btn-primary', 'btn-lg', { exact: true }).
- Split into two assertions: a regex match without exact, plus a separate exact string check.
Example fix
// before
expect(el).toHaveClass(/btn-\w+/, { exact: true })
// after
expect(el).toHaveClass('btn-primary', 'btn-lg', { exact: true }) Defensive patterns
Strategy: validation
Validate before calling
function hasRegExpExpected(classes: (string | RegExp)[]): boolean {
return classes.some(c => c instanceof RegExp)
}
const expected: (string | RegExp)[] = [/btn-\w+/]
const exact = !hasRegExpExpected(expected)
expect(el).toHaveClass(...(exact ? expected.map(String) : expected), { exact }) Prevention
- Never combine { exact: true } with RegExp class names.
- Convert regexes to literal class names when exact set comparison is needed.
When it happens
Trigger: Calling expect(el).toHaveClass(/btn-.*/, { exact: true }) or expect(el).toHaveClass('active', /icon-\w+/, { exact: true }).
Common situations: Copy-paste from a string-based exact assertion where a regex was later substituted; mixing exact class-set checks with flexible pattern matches.
Related errors
- .toContainHTML() expects a string value, got ${htmlText}
- .toHaveDisplayValue() currently supports only input, textare
- .toHaveDisplayValue() currently does not support input[type=
- Invalid element or locator: ${elementOrLocator}. Expected an
- You must provide an array or set to ${matcherHint('.toBeOneO
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/79cc1f6b60587c90.json.
Report an issue: GitHub.