apache/beam · error
node %v is reachable by edge %v, but it's not in same graph
Error message
node %v is reachable by edge %v, but it's not in same graph
What it means
Graph.Build() keeps a map of nodes reachable via edges and verifies each reachable node exists in the current graph's node set. When an edge points to a node that was created in (or attributed to) a different Graph, Build returns "node %v is reachable by edge %v, but it's not in same graph" — a graph-identity invariant violation.
Source
Thrown at sdks/go/pkg/beam/core/graph/graph.go:111
}
// 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())
}
return fmt.Sprintf("Nodes: %v\nEdges: %v", strings.Join(nodes, "\n"), strings.Join(edges, "\n"))
}
View on GitHub (pinned to 12126d8942)
Solutions
- Ensure every node referenced by an edge was created with the same Graph instance (same g.NewNode call chain).
- Don't reuse PCollection/node values across pipeline or graph scopes; recreate them in the new graph.
- Refactor custom transforms to receive the Graph from a single owner instead of constructing their own.
- If hit via normal beam.Pipeline usage, this indicates an SDK bug — report with a minimal repro and pin/upgrade Beam version.
Defensive patterns
Strategy: validation
Prevention
- Use a single Graph instance for all node/edge creation in custom transforms.
- Never reuse nodes/PCollections across pipeline or graph scopes.
When it happens
Trigger: Building a Graph where an edge's Output.To (or Input.From) node was created by another Graph instance, e.g. mixing nodes across two g := graph.New() scopes or reusing nodes from a previous pipeline in a new one.
Common situations: Low-level custom transform code that creates nodes with one graph but edges with another; sharing PCollections/nodes between pipelines; copy-pasted graph-construction code using stale variables.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- node %v in graph is unconnected
- too few params
- too few inputs: forgot an input or to annotate options?
- too many inputs
- needs at least 1 input
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2a2953b08853a11a.
Report an issue: GitHub.