gastownhall/beads · error
edge %d %s->%s: checking planned blocking cycle: %w
Error message
edge %d %s->%s: checking planned blocking cycle: %w
What it means
Wrapper error returned when graphApplyHasPath fails (an underlying storage/tx error) while checking whether a planned edge would close a blocking cycle. The %w preserves the underlying cause; the message is context, not the root problem.
Source
Thrown at cmd/bd/graph_apply.go:1144
continue
}
fromID := resolveEdgeRef(edge.FromKey, edge.FromID, keyToID)
toID := resolveEdgeRef(edge.ToKey, edge.ToID, keyToID)
if fromID == "" || toID == "" {
continue
}
if fromID == toID {
return fmt.Errorf("edge %d %s->%s creates a blocking dependency cycle", i, fromID, toID)
}
adj[fromID] = append(adj[fromID], toID)
checks = append(checks, plannedEdge{index: i, fromID: fromID, toID: toID})
}
depCache := make(map[string][]*types.Dependency)
for _, edge := range checks {
hasPath, err := graphApplyHasPath(ctx, tx, adj, depCache, edge.toID, edge.fromID, graphApplyCycleRelevantDependencyType)
if err != nil {
return fmt.Errorf("edge %d %s->%s: checking planned blocking cycle: %w", edge.index, edge.fromID, edge.toID, err)
}
if hasPath {
return fmt.Errorf("edge %d %s->%s creates a blocking dependency cycle", edge.index, edge.fromID, edge.toID)
}
}
return nil
}
// validateGraphApplyPlannedParentBlockingPaths rejects plans where a planned
// blocking edge would create a path from a parent to its child. Unlike
// validateGraphApplyPlannedBlockingCycles, its existing-dep walk follows the
// full AffectsReadyWork set (blocks, conditional-blocks, parent-child,
// waits-for) because a parent→child path closed through any ready-affecting
// dependency is a real ready-work deadlock. The two predicates must stay
// distinct: narrowing this one would miss real deadlocks, while this broader
// walk may additionally reject a return path through waits-for.
func validateGraphApplyPlannedParentBlockingPaths(ctx context.Context, tx storage.Transaction, plan *GraphApplyPlan, keyToID map[string]string, parentDepPairs map[string]bool) error {
adj := make(map[string][]string)View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped cause at the end of the message and fix that underlying error first
- Retry the apply once storage is healthy
- If GetDependencyRecords keeps failing, verify database integrity for the involved issues
Defensive patterns
Strategy: try-catch
Try / catch
if err := bd.GraphApply(ctx, plan); err != nil {
var root error = err
for errors.Unwrap(root) != nil { root = errors.Unwrap(root) }
log.Printf("cycle-check failed, root cause: %v", root) // handle storage error
} Prevention
- Ensure storage is healthy before running apply
- Treat this as a transport/storage failure, not a plan problem
- Retry with backoff on transient DB errors
When it happens
Trigger: bd graph apply plan validation where the dependency lookup inside graphApplyHasPath (e.g. tx.GetDependencyRecords) returns an error for some node reachable during the cycle search.
Common situations: Database/transaction errors, corrupted dependency records, storage backend unavailable during apply.
Related errors
- reading existing dependencies for %s: %w
- not found
- load wisp labels: %w
- applyGraph: node %q: %w
- CountOpenChildren %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7c1831a11f155c86.
Report an issue: GitHub.