vitest-dev/vitest · error · Error
Invalid tags expression: unexpected end of expression in "${
Error message
Invalid tags expression: unexpected end of expression in "${this.expr}" What it means
Thrown by TokenStream.unexpectedToken when the parser needs another primary operand but the stream is already at EOF. This occurs when an operator (&&, ||, or !) is followed by nothing - the expression ends where a tag or group was expected.
Source
Thrown at packages/vitest/src/runtime/runner/utils/tags.ts:192
next(): Token {
return this.tokens[this.pos++]
}
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 {View on GitHub (pinned to d568f8ce37)
Solutions
- Add the missing right-hand operand after the operator: `unit && smoke`.
- Remove the trailing operator if you did not mean to combine anything.
- Ensure every `!` is immediately followed by a tag or group.
Example fix
// before vitest --tag 'unit &&' // after vitest --tag 'unit && smoke'
Defensive patterns
Strategy: validation
Validate before calling
// Reject expressions ending with an operator
function endsWithOperator(expr: string): boolean {
return /(?:&&|\|\||!|\band\b|\bor\b|\bnot\b)\s*$/i.test(expr.trim())
} Prevention
- Ensure every operator has a right-hand operand.
- Do not end an expression with &&, ||, or !.
- Build filter expressions programmatically rather than by string concatenation.
When it happens
Trigger: A trailing operator: `--tag 'unit &&'`, `--tag 'unit ||'`, or a leading/trailing `!` with nothing after, e.g. `--tag '!'`.
Common situations: Accidentally truncating a filter expression. Editing a filter and deleting the last tag. Using `!` alone expecting negation of everything.
Related errors
- Invalid tags expression: unexpected "${formatToken(stream.pe
- Invalid tags expression: missing closing ")" in "${this.expr
- Invalid tags expression: expected "${formatTokenType(type)}"
- Invalid tags expression: unexpected "${formatToken(token)}"
- failed to parse ${options.id}
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/89b61a7f14b3ba53.json.
Report an issue: GitHub.