gastownhall/beads · error
add deps[%d]: hierarchy check: %w
Error message
add deps[%d]: hierarchy check: %w
What it means
Before inserting each blocking edge, AddDependencies calls ValidateBlockingHierarchy on the repository. This error wraps any failure of that check other than a *DependencyHierarchyConflictError (which is returned unwrapped so callers can errors.As it). It means the hierarchy validation itself failed to run (storage error) or returned a non-typed error.
Source
Thrown at internal/storage/domain/dependency.go:730
wispSources, err := u.depRepo.WispSourceIDs(ctx, sources)
if err != nil {
return BulkAddDepsResult{}, fmt.Errorf("add deps: classify sources: %w", err)
}
// Parent-child edges must be visible before blocking edges in the same
// request. The shared repository guard can then evaluate existing + planned
// ancestry without widening #4034 into #4035's combined-graph cycle check.
for phase := 0; phase < 2; phase++ {
parentPhase := phase == 0
for i, dep := range deps {
if (dep.Type == types.DepParentChild) != parentPhase {
continue
}
if err := u.depRepo.ValidateBlockingHierarchy(ctx, dep); err != nil {
var hierarchyConflict *DependencyHierarchyConflictError
if errors.As(err, &hierarchyConflict) {
return BulkAddDepsResult{}, err
}
return BulkAddDepsResult{}, fmt.Errorf("add deps[%d]: hierarchy check: %w", i, err)
}
if !opts.SkipPerEdgeCycleCheck && types.IsSchedulingEdge(dep.Type) {
cycle, err := u.depRepo.HasCycle(ctx, dep.IssueID, dep.DependsOnID)
if err != nil {
return BulkAddDepsResult{}, fmt.Errorf("add deps[%d]: cycle check: %w", i, err)
}
if cycle {
return BulkAddDepsResult{}, cycleErrorf("add deps[%d]: adding %s -> %s would create a cycle", i, dep.IssueID, dep.DependsOnID)
}
}
// The explicit `bd dep add` / `bd link` verb on the proxied server
// (cmd/bd/dep_proxied_server.go, link_proxied_server.go) records a
// dependency_added event for each genuine new edge — unlike
// create-with-deps, which calls depRepo.Insert directly without
// EmitEvent. UseWispsTable routes both the edge and that event to
// the source's own pair of tables.
_, sourceIsWisp := wispSources[dep.IssueID]
if err := u.depRepo.Insert(ctx, dep, actor, DepInsertOpts{View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped error after the 'hierarchy check:' prefix to find the real cause
- If you expected a hierarchy conflict (e.g. blocking a child against its parent), match *DependencyHierarchyConflictError via errors.As — that path returns the typed error directly
- Retry after confirming database health (bd doctor)
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check parent-child relationships so blocking edges you know conflict // with ancestry are not submitted at all
Type guard
var hc *domain.DependencyHierarchyConflictError
if errors.As(err, &hc) { /* typed hierarchy conflict: handle specifically */ } Try / catch
if err != nil {
var hc *domain.DependencyHierarchyConflictError
if errors.As(err, &hc) { return err } // typed path
// otherwise wrapped as 'hierarchy check:' — storage issue, inspect cause
} Prevention
- Match *DependencyHierarchyConflictError with errors.As for policy conflicts
- Verify ancestry (parent/child) of endpoints before adding blocking edges
- Keep database healthy to avoid traversal failures on large graphs
When it happens
Trigger: Calling AddDependencies with a scheduling/blocking edge where depRepo.ValidateBlockingHierarchy returns an error that is not a DependencyHierarchyConflictError — e.g. a query failure while walking parent-child ancestry.
Common situations: Storage backend errors during ancestry traversal; partially corrupted dependency tables; context cancellation mid-hierarchy-walk on a large graph.
Related errors
- no store is open for this workspace
- no absolute native user directory is available
- ExternalDoltConfig: set either Socket OR (Host, Port), not b
- ExternalDoltConfig: must set Socket or (Host, Port)
- ExternalDoltConfig: Host requires Port
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7cef9534074ff68d.
Report an issue: GitHub.