microsoft/autogen · error · ValueError

Graph has no nodes.

Error message

Graph has no nodes.

What it means

Raised by DiGraph.graph_validate when the graph contains no nodes at all. Every GraphFlow needs at least one node to execute; an empty graph (only a DiGraphBuilder with set_start_node on nothing, or no add_edge calls) is a construction bug and is rejected immediately at team creation time.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_graph/_digraph_group_chat.py:210

        has_cycle = False
        for node in self.nodes:
            if node not in visited:
                if dfs(node):
                    has_cycle = True

        return has_cycle

    def get_has_cycles(self) -> bool:
        """Indicates if the graph has at least one cycle (with valid exit conditions)."""
        if self._has_cycles is None:
            self._has_cycles = self.has_cycles_with_exit()

        return self._has_cycles

    def graph_validate(self) -> None:
        """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

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Ensure at least one builder.add_edge(source_agent, target_agent) call creates a node before GraphFlow(...).
  2. If the graph is generated dynamically, assert non-empty node set before constructing the flow.
  3. Check that set_start_node refers to a node actually created via add_edge.

Example fix

// before
builder = DiGraphBuilder()
flow = GraphFlow(builder)  # no edges/nodes

// after
builder = DiGraphBuilder()
builder.add_edge(starter, finisher)
flow = GraphFlow(builder)
Defensive patterns

Strategy: validation

Validate before calling

if not builder.nodes:
    raise ValueError("Graph is empty: add at least one add_edge(...) before GraphFlow")
flow = GraphFlow(participants, graph_builder=builder)

Type guard

def graph_has_nodes(builder: DiGraphBuilder) -> bool:
    return len(builder.nodes) > 0

Try / catch

try:
    flow = GraphFlow(participants, graph_builder=builder)
except ValueError as e:
    if "Graph has no nodes" in str(e):
        # builder was never populated; add edges first
        ...

Prevention

When it happens

Trigger: Building a DiGraphBuilder and forgetting any add_edge calls (nodes are only created via edges); dynamically generating a graph from config where the node list came out empty; calling GraphFlow with an empty builder.

Common situations: Config-driven graph construction where a filter accidentally removes all nodes; refactoring graph-building code and dropping the edge additions; early scaffolding code that wires the team before the graph is populated.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/1f259cef837df9ee. Report an issue: GitHub.