{"record":{"id":"b116041d8c1a9499","repo":"AtsushiSakai/PythonRobotics","slug":"root-name-action-node-must-have-no-children","errorCode":null,"errorMessage":"{root.name} Action node must have no children","messagePattern":"(.+?) Action node must have no children","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"MissionPlanning/BehaviorTree/behavior_tree.py","lineNumber":638,"sourceCode":"        Returns:\n            BehaviorTree Node: the built node\n        \"\"\"\n        if node.tag in self.node_builders:\n            root = self.node_builders[node.tag](node)\n            if root.type == NodeType.CONTROL_NODE:\n                if len(node) <= 0:\n                    raise ValueError(f\"{root.name} Control node must have children\")\n                for child in node:\n                    root.children.append(self.build_node(child))\n            elif root.type == NodeType.DECORATOR_NODE:\n                if len(node) != 1:\n                    raise ValueError(\n                        f\"{root.name} Decorator node must have exactly one child\"\n                    )\n                root.child = self.build_node(node[0])\n            elif root.type == NodeType.ACTION_NODE:\n                if len(node) != 0:\n                    raise ValueError(f\"{root.name} Action node must have no children\")\n            return root\n        else:\n            raise ValueError(f\"Unknown node type: {node.tag}\")\n\n    def build_tree(self, xml_string):\n        \"\"\"\n        Build a behavior tree from an XML string.\n\n        Args:\n            xml_string (str): The XML string containing the behavior tree.\n\n        Returns:\n            BehaviorTree: The behavior tree.\n        \"\"\"\n        xml_tree = ET.fromstring(xml_string)\n        root = self.build_node(xml_tree)\n        return BehaviorTree(root)\n","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/MissionPlanning/BehaviorTree/behavior_tree.py#L620-L656","documentation":"Raised by build_node when an action-node tag in the XML contains child elements. Action nodes are leaves and must be empty tags; any nested element is treated as a malformed tree.","triggerScenarios":"XML like <ActionA name=\"a\"><ActionB name=\"b\"/></ActionA>.","commonSituations":"Authoring errors where an action is accidentally given children, often from copy-pasting a control node block and renaming the tag.","solutions":["Remove child elements from action tags in the XML.","If child behavior is needed, switch the tag to a control node type (e.g. Sequence) instead.","Validate XML structure before build_tree."],"exampleFix":"<!-- before -->\n<ActionA name=\"a\">\n  <ActionB name=\"b\"/>\n</ActionA>\n\n<!-- after -->\n<ActionA name=\"a\"/>","handlingStrategy":"validation","validationCode":"for el in root.iter():\n    if el.tag in ACTION_TAGS and len(el) != 0:\n        raise ValueError(f'{el.tag} {el.get(\"name\")} must be a leaf')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep action tags empty (self-closing).","Use a tag taxonomy (action vs control vs decorator) when editing tree XML."],"tags":["behavior-tree","xml-parsing","action-node"],"backgroundTag":"xml-schema-validation-failed","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}