microsoft/autogen · error · ValueError
Node '{node.name}' has a mix of conditional and unconditiona
Error message
Node '{node.name}' has a mix of conditional and unconditional edges. What it means
Raised by DiGraph.graph_validate per node when a single node has both conditional edges (with condition= or condition_function=) and unconditional edges. Mixing the two on one node makes branching ambiguous (the unconditional edge always fires, so the conditions can never steer), so validation requires a node's outgoing edges to be either all conditional or all unconditional.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_graph/_digraph_group_chat.py:226
"""Validate graph structure and execution rules."""
if not self.nodes:
raise ValueError("Graph has no nodes.")
if not self.get_start_nodes():
raise ValueError("Graph must have at least one start node")
if not self.get_leaf_nodes():
raise ValueError("Graph must have at least one leaf node")
# Outgoing edge condition validation (per node)
for node in self.nodes.values():
# Check that if a node has an outgoing conditional edge, then all outgoing edges are conditional
has_condition = any(
edge.condition is not None or edge.condition_function is not None for edge in node.edges
)
has_unconditioned = any(edge.condition is None and edge.condition_function is None for edge in node.edges)
if has_condition and has_unconditioned:
raise ValueError(f"Node '{node.name}' has a mix of conditional and unconditional edges.")
# Validate activation conditions across all edges in the graph
self._validate_activation_conditions()
self._has_cycles = self.has_cycles_with_exit()
def _validate_activation_conditions(self) -> None:
"""Validate that all edges pointing to the same target node have consistent activation_condition values.
Raises:
ValueError: If edges pointing to the same target have different activation_condition values
"""
target_activation_conditions: Dict[str, Dict[str, str]] = {} # target_node -> {activation_group -> condition}
for node in self.nodes.values():
for edge in node.edges:
target = edge.target # The target node this edge points to
activation_group = edge.activation_groupView on GitHub (pinned to 027ecf0a37)
Solutions
- Make every outgoing edge of that node conditional, encoding the default branch as condition="..." / condition_function=... returning True when no other branch matches.
- Or keep all edges of the node unconditional (single-path) and move the branching to a downstream node.
- Name the node from the error message to locate the offending edges quickly.
Example fix
// before builder.add_edge(router, fast_path) builder.add_edge(router, slow_path, condition="complex task") # mixed // after builder.add_edge(router, fast_path, condition="simple task") builder.add_edge(router, slow_path, condition="complex task")
Defensive patterns
Strategy: validation
Validate before calling
for name, node in builder.nodes.items():
conditional = [e for e in node.edges if e.condition is not None or e.condition_function is not None]
unconditional = [e for e in node.edges if e.condition is None and e.condition_function is None]
if conditional and unconditional:
raise ValueError(f"Node '{name}' mixes conditional and unconditional outgoing edges") Type guard
def node_edges_are_uniform(node) -> bool:
flags = [(e.condition is not None or e.condition_function is not None) for e in node.edges]
return all(flags) or not any(flags) Try / catch
try:
flow = GraphFlow(participants, graph_builder=builder)
except ValueError as e:
if "mix of conditional and unconditional edges" in str(e):
# make all outgoing edges of the named node conditional (encode default as a condition)
... Prevention
- Treat every router node as fully conditional; encode the default branch as an explicit condition.
- Review a node's outgoing edges as a group when editing a graph.
- Add a structural lint pass over builder.nodes in tests.
When it happens
Trigger: builder.add_edge(a, b) followed by builder.add_edge(a, c, condition="x") — node a mixes both kinds; adding a 'default' fallback edge next to conditional edges; incremental edits that add one conditional edge to a previously unconditional fan-out.
Common situations: Trying to express 'if X go to c, otherwise always go to b' — which this API does not support directly; refactoring a router node; copying edge definitions from different examples into one node.
Related errors
- Cycle detected without exit condition: {' -> '.join(cycle_no
- Graph has no nodes.
- Graph must have at least one start node
- Graph must have at least one leaf node
- Conflicting activation conditions for target '{target}' grou
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/92f889c241a0cb94.
Report an issue: GitHub.