gastownhall/beads · error
edge %d: to key %q not found in plan
Error message
edge %d: to key %q not found in plan
What it means
Plan edges may specify their destination via to_key or to_id. If to_key is set, it must match a node key in the plan; an unknown to_key means the edge target cannot be resolved and the apply is rejected.
Source
Thrown at cmd/bd/graph_apply.go:597
for j, dep := range node.Deps {
if dep.Target == "" {
return fmt.Errorf("node %q: dep %d has empty target", node.Key, j)
}
if dep.Type != "" {
dt := types.DependencyType(dep.Type)
if !dt.IsValid() {
return fmt.Errorf("node %q: dep %d: invalid dependency type %q", node.Key, j, dep.Type)
}
}
}
}
for i, edge := range plan.Edges {
if edge.FromKey != "" && !seenKeys[edge.FromKey] {
return fmt.Errorf("edge %d: from key %q not found in plan", i, edge.FromKey)
}
if edge.ToKey != "" && !seenKeys[edge.ToKey] {
return fmt.Errorf("edge %d: to key %q not found in plan", i, edge.ToKey)
}
if edge.FromKey == "" && edge.FromID == "" {
return fmt.Errorf("edge %d: must specify from_key or from_id", i)
}
if edge.ToKey == "" && edge.ToID == "" {
return fmt.Errorf("edge %d: must specify to_key or to_id", i)
}
if edge.Type != "" {
dt := types.DependencyType(edge.Type)
if !dt.IsValid() {
return fmt.Errorf("edge %d: invalid dependency type %q", i, edge.Type)
}
}
if edge.Gate != "" || edge.SpawnerKey != "" || edge.SpawnerID != "" {
if graphApplyDependencyType(edge.Type) != types.DepWaitsFor {
return fmt.Errorf("edge %d: gate/spawner fields require type %q", i, types.DepWaitsFor)
}
if edge.Gate != "" && !types.IsValidWaitsForGate(edge.Gate) {View on GitHub (pinned to 71377f2769)
Solutions
- Correct to_key to an existing node key in the plan
- Add the missing target node to plan.nodes
- Remove the stale edge, or use to_id referencing a real issue id
Example fix
// before
{"edges": [{"from_key": "build", "to_key": "depoy"}]}
// after
{"edges": [{"from_key": "build", "to_key": "deploy"}]} Defensive patterns
Strategy: validation
Validate before calling
keys := map[string]bool{}
for _, n := range plan.Nodes { keys[n.Key] = true }
for i, e := range plan.Edges {
if e.ToKey != "" && !keys[e.ToKey] { return fmt.Errorf("edge %d: unknown to_key %s", i, e.ToKey) }
} Try / catch
if err := bd.GraphApply(ctx, plan, opts); err != nil {
if strings.Contains(err.Error(), "to key") && strings.Contains(err.Error(), "not found in plan") {
// fix edge target and retry
}
} Prevention
- Build edges from node objects (passing keys) instead of typing keys by hand
- Regenerate edges whenever node keys change
- Validate all edge endpoints against plan keys before applying
When it happens
Trigger: `bd graph apply` with plan.edges[i].to_key naming a key absent from plan.nodes.
Common situations: Typos in to_key; the target node was deleted from the plan while its incoming edges remained; merging plans whose key namespaces differ.
Related errors
- node %q: metadata ref %q references unknown key %q
- node %q: parent key %q not found in plan
- edge %d: from key %q not found in plan
- duplicate node key %q
- node %q has empty title
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/48441cac97c5ea2e.
Report an issue: GitHub.