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 is at a position requiring a primary expression (a tag or a `(`) but the current token is EOF — i.e. the expression ended prematurely. This happens when a binary or unary operator has nothing after it.
Solutions
- Add the missing operand after the trailing operator: `--tags 'foo && bar'`.
- Remove the trailing operator if no second operand is intended: `--tags 'foo'`.
- Ensure every `!`/`not` is followed by a tag or parenthesized sub-expression.
Example fix
# before vitest --tags 'smoke &&' # after vitest --tags 'smoke && critical'
Defensive patterns
Strategy: validation
Validate before calling
function noTrailingOperator(expr: string): boolean {
return !/(?:&&|\|\||!|\bnot\b|\band\b|\bor\b)\s*$/i.test(expr.trim())
} Prevention
- When constructing filters in code, filter out empty fragments before joining.
- Visually confirm every operator has a right-hand operand.
- Avoid trailing whitespace after operators when editing by hand.
When it happens
Trigger: A `--tags` expression ending with a binary operator (`vitest --tags 'foo &&'`, `vitest --tags 'foo ||'`), a `not`/`!` with no following tag (`vitest --tags '!'` or `--tags 'not'`), or an empty expression after an operator inside parens (`--tags '(foo && )'` would surface via 344, but a bare trailing `&&` hits 345).
Common situations: Trailing operator typed by accident; the tag name after an operator was deleted; building the expression programmatically and leaving a dangling operator.
Related errors
- Invalid tags expression: expected
- Invalid tags expression: missing closing ")" in
- Invalid tags expression: unexpected
- 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/89b61a7f14b3ba53.
Report an issue: GitHub.
Appendix: 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 1fa9837ec2)