{"record":{"id":"fb905b9ab8e8000b","repo":"nodejs/node","slug":"unsupported-arity-len-expr-children","errorCode":null,"errorMessage":"Unsupported arity {len(expr.children)}","messagePattern":"Unsupported arity (.+?)","errorType":"validation","errorClass":"UnsupportedOperation","httpStatus":null,"severity":"error","filePath":"deps/v8/tools/cppgc/gen_cmake.py","lineNumber":190,"sourceCode":"        '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,\n        'condition': _Condition,\n    }\n\n    ASSIGN_TYPES = {\n        'asgn_op': _AssignEq,\n        'asgn_add_op': _AssignAdd,","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/v8/tools/cppgc/gen_cmake.py#L172-L208","documentation":"gen_cmake.py supports only unary (1 child) and binary (2 children) expression nodes. After the OPS membership check passes, if the node has neither 1 nor 2 children the code can't decide what to build and raises UnsupportedOperation, signalling a structural problem in the parsed tree rather than silently picking an arity.","triggerScenarios":"Raised in _Expr() when `len(expr.children)` is neither 1 nor 2 for a valid operator node. Fires after the unary/binary branches, so it's the catch-all for 0-child or 3+-child operator nodes.","commonSituations":"Grammar rule change that lets an operator take a variable/tuple arity (e.g. ternary) without a corresponding builder; malformed input that lark parsed into an unexpected tree shape; hand-edited parse tree in tests.","solutions":["Inspect the parse tree (print expr.pretty()) to see why the operator got the wrong child count.","If a new arity is intentional, add an explicit branch (e.g. _TernaryExpr) before this final raise.","Fix the input/grammar so the operator only ever has 1 or 2 children."],"exampleFix":"# before: grammar allows ternary `cond ? a : b` as one operator node\n# after: rewrite as nested binary (cond AND a) OR b, or add a _TernaryExpr branch","handlingStrategy":"type-guard","validationCode":"n = len(expr.children)\nassert n in (1,2), f'operator {expr.data} has unsupported arity {n}'","typeGuard":"def is_supported_arity(expr):\n    return len(expr.children) in (1, 2)","tryCatchPattern":null,"preventionTips":["If you extend the grammar to a new arity, add the matching builder branch before the raise.","Dump expr.pretty() in tests to catch unexpected tree shapes early."],"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"}