AtsushiSakai/PythonRobotics · error · ValueError

Control node must have children

Error message

{root.name} Control node must have children

What it means

Raised by BehaviorTree XML builder's build_node when a control-node tag (sequence, selector, while-do-else) contains no child elements. Control nodes need children to execute, so an empty tag in the XML is a structural error.

Solutions

  1. Add at least one child element inside the control tag in the XML.
  2. Validate the XML against your tree schema before build_tree.
  3. Check for self-closing control tags (<Sequence .../>).

Example fix

<!-- before -->
<Sequence name="s"/>

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

Strategy: validation

Validate before calling

import xml.etree.ElementTree as ET
root = ET.fromstring(xml_string)
for el in root.iter():
    if el.tag in CONTROL_TAGS and len(el) == 0:
        raise ValueError(f'{el.tag} {el.get("name")} has no children')

Try / catch

try:
    tree = builder.build_tree(xml_string)
except ValueError as e:
    if 'must have children' in str(e):
        fix_and_retry(xml_string)
    raise

Prevention

When it happens

Trigger: Parsing XML like <Sequence name="s"/> or <Sequence name="s"></Sequence> with build_tree/build_node.

Common situations: Hand-written or template-generated XML tree files where a control tag is left empty or children are commented out.

Related errors


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

Appendix: source

Thrown at MissionPlanning/BehaviorTree/behavior_tree.py:627

                )
        """
        self.node_builders[node_name] = builder

    def build_node(self, node):
        """
        Build a node from an XML element.

        Args:
            node (Element): The XML element to build the node from.

        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.

View on GitHub (pinned to 1fe4fb980f)