vitest-dev/vitest · error · Error
Invalid tags expression: unexpected
Error message
Invalid tags expression: unexpected "${formatToken(token)}" in "${this.expr}" What it means
Thrown by TokenStream.unexpectedToken when the parser is at a primary-expression position and the current token is neither a tag nor a left-paren (and is not EOF, which is handled separately by error 345). The message names the offending token so the user can locate it.
Solutions
- Start the expression (and every sub-expression) with a tag name or `(`: `--tags 'foo'` or `--tags '(foo || bar)'`.
- Remove the leading/stray operator identified by 'unexpected' in the message.
- When building filters in code, join non-empty fragments only: `parts.filter(Boolean).join(' && ')`.
Example fix
# before vitest --tags '&& smoke' # after vitest --tags 'smoke'
Defensive patterns
Strategy: validation
Validate before calling
function startsWithTagOrParen(expr: string): boolean {
return /^\s*(?:!?[\w*-]+|\()/.test(expr)
} Prevention
- Never begin an expression (or a sub-expression after `(`) with an operator.
- When building filters dynamically, trim leading operators: s.replace(/^(?:&&|\|\|)+/, '').
- Validate generated expressions with a tiny parser/test before passing to vitest.
When it happens
Trigger: A `--tags` filter starting with a binary operator (`vitest --tags '&& foo'`), a `)` with no matching `(` (`vitest --tags 'foo)'` — though this often hits 342), a leading operator inside a group (`--tags '(&& foo)'`), or any token that cannot begin a primary expression.
Common situations: Pasting an expression and losing its first token; building filters dynamically and joining with a leading `&&`/`||`; stray punctuation; mismatched parentheses producing a `)` where a value is expected.
Related errors
- Invalid tags expression: expected
- Invalid tags expression: missing closing ")" in
- Invalid tags expression: unexpected end of expression in
- Invalid tags expression: unexpected
- Unknown value for "test.listTags
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/3c8a25a7767e4162.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/runner/utils/tags.ts:194
}
expect(type: Token['type']): Token {
const token = this.next()
if (token.type !== type) {
if (type === 'RPAREN' && token.type === 'EOF') {
throw new Error(`Invalid tags expression: missing closing ")" in "${this.expr}"`)
}
throw new Error(`Invalid tags expression: expected "${formatTokenType(type)}" but got "${formatToken(token)}" in "${this.expr}"`)
}
return token
}
unexpectedToken(): never {
const token = this.peek()
if (token.type === 'EOF') {
throw new Error(`Invalid tags expression: unexpected end of expression in "${this.expr}"`)
}
throw new Error(`Invalid tags expression: unexpected "${formatToken(token)}" in "${this.expr}"`)
}
}
function formatTokenType(type: Token['type']): string {
switch (type) {
case 'TAG': return 'tag'
case 'AND': return 'and'
case 'OR': return 'or'
case 'NOT': return 'not'
case 'LPAREN': return '('
case 'RPAREN': return ')'
case 'EOF': return 'end of expression'
}
}
function parseOrExpression(stream: TokenStream, availableTags: TestTagDefinition[]): ASTNode {
let left = parseAndExpression(stream, availableTags)
View on GitHub (pinned to 1fa9837ec2)