gastownhall/beads · error
failed to check blocker ancestry: %w
Error message
failed to check blocker ancestry: %w
What it means
Wraps an error from isAncestorInTx while CheckBlockingHierarchyInTx checks whether the blocker is an ancestor of the dependent issue in the hierarchy. This is not the hierarchy-conflict result itself (that is a DependencyHierarchyConflictError); it means the ancestry lookup query failed, so the hierarchy validation could not complete.
Source
Thrown at internal/storage/issueops/dependencies.go:532
return []string{"dependencies", "wisp_dependencies"}
}
// CheckBlockingHierarchyInTx rejects blocking dependencies between an issue
// and its own ancestor or descendant. Cross-prefix/external targets must be
// filtered by the caller because no local hierarchy can connect them.
func CheckBlockingHierarchyInTx(ctx context.Context, tx DBTX, dep *types.Dependency, depTables []string) error {
if dep.Type != types.DepBlocks && dep.Type != types.DepConditionalBlocks {
return nil
}
if dep.IssueID == dep.DependsOnID {
return nil // The dedicated self-dependency check owns this error.
}
if len(depTables) == 0 {
depTables = cycleDetectionTables()
}
blockerIsAncestor, err := isAncestorInTx(ctx, tx, dep.IssueID, dep.DependsOnID, depTables)
if err != nil {
return fmt.Errorf("failed to check blocker ancestry: %w", err)
}
if blockerIsAncestor {
return &domain.DependencyHierarchyConflictError{
IssueID: dep.IssueID, BlockerID: dep.DependsOnID, BlockerIsAncestor: true,
}
}
blockerIsDescendant, err := isAncestorInTx(ctx, tx, dep.DependsOnID, dep.IssueID, depTables)
if err != nil {
return fmt.Errorf("failed to check blocker ancestry: %w", err)
}
if blockerIsDescendant {
return &domain.DependencyHierarchyConflictError{
IssueID: dep.IssueID, BlockerID: dep.DependsOnID,
}
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause for the underlying SQL error and address it
- Retry the operation; the ancestry check is read-only and the tx rolls back cleanly
- Validate parent chains of both issues (no dangling parent IDs) before adding the dependency
- Check for lock contention from concurrent hierarchy mutations and serialize writes
Example fix
// before
if err := issueops.CheckBlockingHierarchyInTx(ctx, tx, dep, nil); err != nil {
return err
}
// after
if err := issueops.CheckBlockingHierarchyInTx(ctx, tx, dep, nil); err != nil {
var hier *domain.DependencyHierarchyConflictError
if errors.As(err, &hier) {
return err // genuine hierarchy conflict
}
return fmt.Errorf("hierarchy check unavailable, deferring dep add: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure both issues have resolvable parent chains before hierarchy check
if danglingParent(ctx, db, dep.IssueID) || danglingParent(ctx, db, dep.DependsOnID) {
return errors.New("cannot validate hierarchy: dangling parent reference")
} Type guard
func isAncestryInfraFailure(err error) bool {
var hier *domain.DependencyHierarchyConflictError
return err != nil && !errors.As(err, &hier) &&
strings.Contains(err.Error(), "failed to check blocker ancestry")
} Try / catch
err := issueops.CheckBlockingHierarchyInTx(ctx, tx, dep, nil)
var hier *domain.DependencyHierarchyConflictError
switch {
case errors.As(err, &hier):
return err // genuine hierarchy conflict
case err != nil:
return retryWithBackoff(op) // ancestry lookup failed, not a conflict
} Prevention
- Use errors.As with DependencyHierarchyConflictError to separate real conflicts from infra failures
- Keep parent links free of dangling IDs
- Retry after transient DB failures; the tx rolls back cleanly
- Serialize hierarchy mutations to avoid traversal races
When it happens
Trigger: CheckBlockingHierarchyInTx invoked (via addDependencyInTx, PersistDependenciesWithOptionsResult, or runEndGate) with empty depTables defaulted to cycleDetectionTables, and isAncestorInTx errors on its traversal — DB failure, aborted tx, or corrupted hierarchy rows.
Common situations: Database connectivity loss during dep-add or an end-gate run; concurrent renames of issues invalidating traversal mid-tx; malformed parent links in the issues table.
Related errors
- ErrTransaction
- open unit of work: %w
- failed to begin transaction: %w
- failed to commit is_blocked repairs: %w
- failed to begin transaction: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7c41203d58b5c2c4.
Report an issue: GitHub.