nodejs/node · error · UnsupportedOperation

The operator "{expr.data}" is not supported

Error message

The operator "{expr.data}" is not supported

What it means

V8's gen_cmake.py turns a parsed boolean expression tree (via lark) into CMake generator expressions. Each interior node's `data` field must name a known operator in the OPS set. Hitting a node whose data isn't in OPS means the grammar accepted an operator the code generator hasn't wired up, so it raises UnsupportedOperation rather than emit wrong CMake.

Source

Thrown at deps/v8/tools/cppgc/gen_cmake.py:184

            assert 'statement_list' == else_stmts.data
            else_stmts = self._StatementList(else_stmts.children)
            return self.builder.BuildConditionWithElseStmts(
                cond_expr, then_stmts, else_stmts)

    def _Expr(self, expr):
        'Post-order traverse expression trees'
        if isinstance(expr, lark.Token):
            if expr.type == 'IDENTIFIER':
                return self.builder.BuildIdentifier(str(expr))
            elif expr.type == 'INTEGER':
                return self.builder.BuildInteger(str(expr))
            else:
                return self.builder.BuildString(str(expr))
        if expr.data == 'par_expr':
            return self.builder.BuildParenthesizedOperation(
                self._Expr(*expr.children))
        if expr.data not in OPS:
            raise UnsupportedOperation(
                f'The operator "{expr.data}" is not supported')
        if len(expr.children) == 1:
            return self._UnaryExpr(expr.data, *expr.children)
        if len(expr.children) == 2:
            return self._BinaryExpr(expr.data, *expr.children)
        raise UnsupportedOperation(f'Unsupported arity {len(expr.children)}')

    def _UnaryExpr(self, op, right):
        right = self._Expr(right)
        return self.builder.BuildUnaryOperation(op, right)

    def _BinaryExpr(self, op, left, right):
        left = self._Expr(left)
        right = self._Expr(right)
        return self.builder.BuildBinaryOperation(left, op, right)

    STATEMENTS = {
        'assignment': _Assignment,

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Register the operator in the OPS mapping and implement BuildUnary/BuildBinaryOperation support for it.
  2. If the operator appeared by mistake, fix the input expression to use only supported operators.
  3. Re-sync the grammar file and gen_cmake.py to a consistent V8 revision.

Example fix

# before: grammar allows `xor` but OPS lacks it
# after
OPS['xor'] = ('STRLESS', ...)  # plus a builder branch
# or: rewrite the input expression without `xor`
Defensive patterns

Strategy: type-guard

Validate before calling

KNOWN_OPS = {'and','or','not','eq','ne'}  # mirror gen_cmake.OPS
assert expr.data in KNOWN_OPS or expr.data == 'par_expr', f'unsupported operator {expr.data}'

Type guard

def is_supported_operator(expr, ops):
    return expr.data in ops or expr.data == 'par_expr'

Prevention

When it happens

Trigger: Raised in _Expr() when `expr.data not in OPS` for a Tree (non-Token) node. Reached after the par_expr case is handled, before unary/binary dispatch on child count.

Common situations: Editing the lark grammar to allow a new operator (xor, implication) without registering it in OPS and the builder; a malformed input the grammar nonetheless parsed as an operator; version skew between the grammar file and gen_cmake.py.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/4e8cfc02f64a6afc. Report an issue: GitHub.