apache/beam · error

node %v in graph is unconnected

Error message

node %v in graph is unconnected

What it means

Graph.Build() checks that every node in g.nodes is reachable via at least one MultiEdge output. A node with no incoming edge means it's disconnected from the pipeline (nothing consumes it), so Build returns 'node %v in graph is unconnected'.

Source

Thrown at sdks/go/pkg/beam/core/graph/graph.go:106

	for _, n := range g.nodes {
		nodes[n] = true
		if n.Coder == nil {
			return nil, nil, errors.Errorf("node %v in graph has undefined coder", n.id)
		}
	}
	// Build a map of all nodes that are reachable by g.edges.
	reachable := make(map[*Node]*MultiEdge)
	for _, e := range g.edges {
		for _, i := range e.Input {
			reachable[i.From] = e
		}
		for _, o := range e.Output {
			reachable[o.To] = e
		}
	}
	for n := range nodes {
		if _, ok := reachable[n]; !ok {
			return nil, nil, errors.Errorf("node %v in graph is unconnected", n.id)
		}
	}
	for n, e := range reachable {
		if _, ok := nodes[n]; !ok {
			return nil, nil, errors.Errorf("node %v is reachable by edge %v, but it's not in same graph", n.id, e.id)
		}
	}
	return g.edges, g.nodes, nil
}

func (g *Graph) String() string {
	var nodes []string
	for _, node := range g.nodes {
		nodes = append(nodes, node.String())
	}
	var edges []string
	for _, edge := range g.edges {
		edges = append(edges, edge.String())

View on GitHub (pinned to 12126d8942)

Solutions

  1. Connect the orphan node to a downstream transform (e.g. pass it as an input to beam.ParDo or a sink like beam.io.Write).
  2. If the PCollection is intentionally unused, remove the transform producing it.
  3. When hand-building graphs, register the node via an edge (g.NewEdge and set Input/Output) before Build().
  4. Review custom composite transform expansion so all outputs are either consumed or deliberately rooted.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Creating a node (e.g. via beam.Impulse/beam.Create output or manual g.NewNode) without wiring it as input to any transform before calling Build().

Common situations: Manually constructing graphs with the low-level API and forgetting to connect an output; a transform whose output PCollection is dropped silently in custom code; SDK bugs when composing custom composite transforms.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/fb4713db77f83199. Report an issue: GitHub.