{"record":{"id":"16faa3a85b598124","repo":"AtsushiSakai/PythonRobotics","slug":"whiledoelsenode-must-have-exactly-3-or-2-children","errorCode":null,"errorMessage":"WhileDoElseNode must have exactly 3 or 2 children","messagePattern":"WhileDoElseNode must have exactly 3 or 2 children","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"MissionPlanning/BehaviorTree/behavior_tree.py","lineNumber":198,"sourceCode":"        If condition fails, executes else node (child[2]) if present and returns result of else node\n        If condition fails and there is no else node, returns SUCCESS\n\n    Example:\n        .. code-block:: xml\n\n            <WhileDoElse>\n                <Condition />\n                <Do />\n                <Else />\n            </WhileDoElse>\n    \"\"\"\n\n    def __init__(self, name):\n        super().__init__(name)\n\n    def tick(self) -> Status:\n        if len(self.children) != 3 and len(self.children) != 2:\n            raise ValueError(\"WhileDoElseNode must have exactly 3 or 2 children\")\n\n        condition_node = self.children[0]\n        do_node = self.children[1]\n        else_node = self.children[2] if len(self.children) == 3 else None\n\n        condition_status = condition_node.tick_and_set_status()\n        if condition_status == Status.SUCCESS:\n            do_node.tick_and_set_status()\n            return Status.RUNNING\n        elif condition_status == Status.FAILURE:\n            if else_node is not None:\n                else_status = else_node.tick_and_set_status()\n                if else_status == Status.SUCCESS:\n                    self.reset_children()\n                    return Status.SUCCESS\n                elif else_status == Status.FAILURE:\n                    self.reset_children()\n                    return Status.FAILURE","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/MissionPlanning/BehaviorTree/behavior_tree.py#L180-L216","documentation":"WhileDoElseNode.tick requires exactly 2 or 3 children: [condition, do] or [condition, do, else]. Any other count raises this before execution because the node's semantics are undefined otherwise.","triggerScenarios":"Adding 1 child, or 4 or more children, to a WhileDoElseNode and ticking it.","commonSituations":"Treating WhileDoElseNode like a generic sequence node and appending many children, or forgetting the optional else branch ordering when assembling the tree from XML.","solutions":["Configure the node with exactly 2 children (condition, do) or 3 children (condition, do, else), in that order.","If you need more branches, use a SelectorNode/SequenceNode combination instead.","Assert the child count after building the tree."],"exampleFix":"// before\nwde.add_child(cond); wde.add_child(do); wde.add_child(else_); wde.add_child(extra)\n\n// after\nwde.add_child(cond); wde.add_child(do); wde.add_child(else_)","handlingStrategy":"validation","validationCode":"assert len(wde.children) in (2, 3), 'WhileDoElseNode needs 2 or 3 children'","typeGuard":"def valid_wde(node) -> bool:\n    return len(node.children) in (2, 3)","tryCatchPattern":null,"preventionTips":["Assemble WhileDoElse nodes via a helper that takes condition, do, else explicitly.","Document child order: condition first."],"tags":["behavior-tree","while-do-else","arity-validation"],"backgroundTag":"wrong-number-of-arguments","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}