AtsushiSakai/PythonRobotics · error · ValueError

{root.name} Action node must have no children

Error message

{root.name} Action node must have no children

What it means

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.

Source

Thrown at MissionPlanning/BehaviorTree/behavior_tree.py:638

        Returns:
            BehaviorTree Node: the built node
        """
        if node.tag in self.node_builders:
            root = self.node_builders[node.tag](node)
            if root.type == NodeType.CONTROL_NODE:
                if len(node) <= 0:
                    raise ValueError(f"{root.name} Control node must have children")
                for child in node:
                    root.children.append(self.build_node(child))
            elif root.type == NodeType.DECORATOR_NODE:
                if len(node) != 1:
                    raise ValueError(
                        f"{root.name} Decorator node must have exactly one child"
                    )
                root.child = self.build_node(node[0])
            elif root.type == NodeType.ACTION_NODE:
                if len(node) != 0:
                    raise ValueError(f"{root.name} Action node must have no children")
            return root
        else:
            raise ValueError(f"Unknown node type: {node.tag}")

    def build_tree(self, xml_string):
        """
        Build a behavior tree from an XML string.

        Args:
            xml_string (str): The XML string containing the behavior tree.

        Returns:
            BehaviorTree: The behavior tree.
        """
        xml_tree = ET.fromstring(xml_string)
        root = self.build_node(xml_tree)
        return BehaviorTree(root)

View on GitHub (pinned to 1fe4fb980f)

Solutions

  1. Remove child elements from action tags in the XML.
  2. If child behavior is needed, switch the tag to a control node type (e.g. Sequence) instead.
  3. Validate XML structure before build_tree.

Example fix

<!-- before -->
<ActionA name="a">
  <ActionB name="b"/>
</ActionA>

<!-- after -->
<ActionA name="a"/>
Defensive patterns

Strategy: validation

Validate before calling

for el in root.iter():
    if el.tag in ACTION_TAGS and len(el) != 0:
        raise ValueError(f'{el.tag} {el.get("name")} must be a leaf')

Prevention

When it happens

Trigger: XML like <ActionA name="a"><ActionB name="b"/></ActionA>.

Common situations: Authoring errors where an action is accidentally given children, often from copy-pasting a control node block and renaming the tag.

Related errors


AI-assisted analysis of AtsushiSakai/PythonRobotics@1fe4fb980f (2026-08-28). Data as JSON: /api/errors/b116041d8c1a9499. Report an issue: GitHub.