{"record":{"id":"4e8cfc02f64a6afc","repo":"nodejs/node","slug":"the-operator-expr-data-is-not-supported","errorCode":null,"errorMessage":"The operator \"{expr.data}\" is not supported","messagePattern":"The operator \"(.+?)\" is not supported","errorType":"validation","errorClass":"UnsupportedOperation","httpStatus":null,"severity":"error","filePath":"deps/v8/tools/cppgc/gen_cmake.py","lineNumber":184,"sourceCode":"            assert 'statement_list' == else_stmts.data\n            else_stmts = self._StatementList(else_stmts.children)\n            return self.builder.BuildConditionWithElseStmts(\n                cond_expr, then_stmts, else_stmts)\n\n    def _Expr(self, expr):\n        'Post-order traverse expression trees'\n        if isinstance(expr, lark.Token):\n            if expr.type == 'IDENTIFIER':\n                return self.builder.BuildIdentifier(str(expr))\n            elif expr.type == 'INTEGER':\n                return self.builder.BuildInteger(str(expr))\n            else:\n                return self.builder.BuildString(str(expr))\n        if expr.data == 'par_expr':\n            return self.builder.BuildParenthesizedOperation(\n                self._Expr(*expr.children))\n        if expr.data not in OPS:\n            raise UnsupportedOperation(\n                f'The operator \"{expr.data}\" is not supported')\n        if len(expr.children) == 1:\n            return self._UnaryExpr(expr.data, *expr.children)\n        if len(expr.children) == 2:\n            return self._BinaryExpr(expr.data, *expr.children)\n        raise UnsupportedOperation(f'Unsupported arity {len(expr.children)}')\n\n    def _UnaryExpr(self, op, right):\n        right = self._Expr(right)\n        return self.builder.BuildUnaryOperation(op, right)\n\n    def _BinaryExpr(self, op, left, right):\n        left = self._Expr(left)\n        right = self._Expr(right)\n        return self.builder.BuildBinaryOperation(left, op, right)\n\n    STATEMENTS = {\n        'assignment': _Assignment,","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/v8/tools/cppgc/gen_cmake.py#L166-L202","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Register the operator in the OPS mapping and implement BuildUnary/BuildBinaryOperation support for it.","If the operator appeared by mistake, fix the input expression to use only supported operators.","Re-sync the grammar file and gen_cmake.py to a consistent V8 revision."],"exampleFix":"# before: grammar allows `xor` but OPS lacks it\n# after\nOPS['xor'] = ('STRLESS', ...)  # plus a builder branch\n# or: rewrite the input expression without `xor`","handlingStrategy":"type-guard","validationCode":"KNOWN_OPS = {'and','or','not','eq','ne'}  # mirror gen_cmake.OPS\nassert expr.data in KNOWN_OPS or expr.data == 'par_expr', f'unsupported operator {expr.data}'","typeGuard":"def is_supported_operator(expr, ops):\n    return expr.data in ops or expr.data == 'par_expr'","tryCatchPattern":null,"preventionTips":["Keep the grammar, OPS mapping, and builder methods in lockstep when adding operators.","Add parse-tree assertions in tests that exercise new grammar productions."],"tags":["v8","cppgc","cmake","codegen","grammar","lark"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}