gastownhall/beads · error
applyGraph: edge %d references undefined to_key %q
Error message
applyGraph: edge %d references undefined to_key %q
What it means
Same fail-fast validation as the from_key check, but applied to the edge's to-side: applyGraph resolves Edges[i].ToKey/ToID against keyToID and aborts the entire graph apply if the dependency target does not exist, preserving failure-before-write semantics.
Source
Thrown at internal/storage/domain/issue.go:1183
parentDepPairs := graphParentDepPairs(plan.Nodes, keyToID)
newSchedulingEdges := make([][2]string, 0, len(plan.Nodes)+len(plan.Edges))
if err := u.validatePlannedBlockingPaths(ctx, plan, keyToID, parentDepPairs); err != nil {
return GraphApplyResult{}, err
}
if err := u.validatePlannedBlockingCycles(ctx, plan, keyToID); err != nil {
return GraphApplyResult{}, err
}
// Preserve failure-before-write for explicit edges that conflict directly
// with an implicit node parent relationship. Parent-first mutation below is
// for transitive hierarchy visibility, not for deferring structural errors.
for i, edge := range plan.Edges {
fromID := resolveEdgeRef(edge.FromKey, edge.FromID, keyToID)
if fromID == "" {
return GraphApplyResult{}, fmt.Errorf("applyGraph: edge %d references undefined from_key %q", i, edge.FromKey)
}
toID := resolveEdgeRef(edge.ToKey, edge.ToID, keyToID)
if toID == "" {
return GraphApplyResult{}, fmt.Errorf("applyGraph: edge %d references undefined to_key %q", i, edge.ToKey)
}
depType := edge.Type
if depType == "" {
depType = types.DepBlocks
}
if parentDepPairs[depPairKey(fromID, toID)] && depType != types.DepParentChild {
return GraphApplyResult{}, fmt.Errorf("applyGraph: edge %d %s->%s duplicates a parent-child relationship with dependency type %q", i, fromID, toID, depType)
}
if parentDepPairs[depPairKey(toID, fromID)] && cycleRelevantDepType(depType) {
return GraphApplyResult{}, fmt.Errorf("applyGraph: edge %d %s->%s creates a blocking reverse of a parent-child relationship", i, fromID, toID)
}
}
// Pass 3 — insert node parent-child deps now that all IDs are known. These
// must be visible before any blocking edge in the same plan so the storage
// hierarchy guard evaluates existing + planned ancestry.
for _, node := range plan.Nodes {
parentID := node.ParentIDView on GitHub (pinned to 71377f2769)
Solutions
- Create the target issue (in the plan or beforehand) so ToKey resolves
- Check the target key with bd show; fix typos
- Use edge.ToID when the UUID is known
- Sync first if the target lives on another machine/remote
Example fix
// before
GraphEdge{FromKey: "bd-1", ToKey: "bd-blocked-by-missing"}
// after
GraphEdge{FromKey: "bd-1", ToKey: "bd-2"} // ensure bd-2 exists or is a node in the same plan Defensive patterns
Strategy: validation
Validate before calling
for _, e := range plan.Edges {
if _, ok := keyToID[e.ToKey]; !ok && e.ToID == "" {
return fmt.Errorf("edge to_key %q not found; create it or add a node", e.ToKey)
}
} Type guard
func edgeToResolved(e GraphEdge, keyToID map[string]string) bool {
_, ok := keyToID[e.ToKey]
return ok || e.ToID != ""
} Prevention
- Validate every edge target exists before applyGraph
- Keep plan construction and application against the same DB snapshot
- Guard against deleted targets by re-reading keys just before apply
- Use consistent issue-key prefixes across environments
When it happens
Trigger: applyGraph plan contains an edge whose ToKey (with no valid ToID) names an issue absent from the DB and from the plan's own nodes.
Common situations: Referencing a blocker that was closed-and-deleted; typo in the dependency target key; plan split across two applies where the target was expected in the other half; key from a different project prefix.
Related errors
- applyGraph: edge %d references undefined from_key %q
- no store is open for this workspace
- not found
- db: ChildCounterSQLRepository.NextChildID: parentID must not
- db: DependencySQLRepository.Insert: dep must not be nil
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/afc17403c42455ff.
Report an issue: GitHub.