AtsushiSakai/PythonRobotics · error · ValueError

Decorator node must have exactly one child

Error message

{root.name} Decorator node must have exactly one child

What it means

Raised by build_node when a decorator-node tag in the XML does not contain exactly one child element. Decorators wrap a single node, so zero or multiple children are structural errors.

Solutions

  1. Give the decorator tag exactly one child element in the XML.
  2. Move extra children out or wrap them in a sequence under the decorator.
  3. Lint the XML tree structure before calling build_tree.

Example fix

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

<!-- after -->
<Inverter name="i">
  <Sequence name="s">
    <ActionA name="a"/>
    <ActionB name="b"/>
  </Sequence>
</Inverter>
Defensive patterns

Strategy: validation

Validate before calling

for el in root.iter():
    if el.tag in DECORATOR_TAGS and len(el) != 1:
        raise ValueError(f'{el.tag} {el.get("name")} must have exactly one child')

Try / catch

try:
    tree = builder.build_tree(xml_string)
except ValueError as e:
    if 'exactly one child' in str(e):
        wrap_extra_children_in_sequence(xml_string)
    raise

Prevention

When it happens

Trigger: XML like <Inverter name="i"/> (zero children) or an Inverter enclosing two child tags.

Common situations: Nesting mistakes in hand-authored XML, or copying a control-node pattern under a decorator tag.

Related errors


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

Appendix: source

Thrown at MissionPlanning/BehaviorTree/behavior_tree.py:632

        """
        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.

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

        Returns:

View on GitHub (pinned to 1fe4fb980f)