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

  1. Read the wrapped cause at the end of the message and fix that underlying error first
  2. Retry the apply once storage is healthy
  3. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/7c1831a11f155c86. Report an issue: GitHub.