gastownhall/beads · error
edge %d: from key %q not found in plan
Error message
edge %d: from key %q not found in plan
What it means
Plan edges may specify their source via from_key or from_id. If from_key is set, it must match a node key in the plan; otherwise the edge's source cannot be resolved and validation fails with the edge index.
Source
Thrown at cmd/bd/graph_apply.go:594
return fmt.Errorf("node %q: parent key %q not found in plan", node.Key, parentKey)
}
}
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 {View on GitHub (pinned to 71377f2769)
Solutions
- Correct from_key to an existing node key in the plan
- Add the missing source node to plan.nodes
- Remove the stale edge, or use from_id referencing a real issue id
Example fix
// before
{"edges": [{"from_key": "buld", "to_key": "deploy"}]}
// 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.FromKey != "" && !keys[e.FromKey] { return fmt.Errorf("edge %d: unknown from_key %s", i, e.FromKey) }
} Try / catch
if err := bd.GraphApply(ctx, plan, opts); err != nil {
if strings.Contains(err.Error(), "from key") && strings.Contains(err.Error(), "not found in plan") {
// fix edge source 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].from_key naming a key absent from plan.nodes.
Common situations: Typos in from_key; the source node was removed from the plan but its edges remained; edges carried over from a different plan with different keys.
Related errors
- node %q: metadata ref %q references unknown key %q
- node %q: parent key %q not found in plan
- edge %d: to 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/d71a45fd307ee2e4.
Report an issue: GitHub.