gastownhall/beads · error
get parent descendants: %w
Error message
get parent descendants: %w
What it means
Wraps failures from getDescendantIDs while resolving the descendants of filter.ParentID during ready-work computation. The descendant lookup runs a recursive CTE over dependency edges; any failure there makes parent-scoped ready work unanswerable. The chain also includes the traversal max-depth guard further down.
Source
Thrown at internal/storage/domain/db/ready_work.go:42
}
// buildReadyWorkPredicates computes the ID sets the ready-work WHERE clause
// needs (children of deferred parents, parent descendants), then delegates
// the clause text to sqlbuild so both stacks share ready semantics. Unlike
// the classic stack, ORDER BY and LIMIT are applied at the UNION outer query.
func (r *issueSQLRepositoryImpl) buildReadyWorkPredicates(ctx context.Context, filter types.WorkFilter, tables filterTables) (*readyWorkPredicates, error) {
var inputs sqlbuild.ReadyWorkWhereInputs
if !filter.IncludeDeferred {
deferredChildIDs, dcErr := r.getChildrenOfDeferredParents(ctx)
if dcErr != nil {
return nil, fmt.Errorf("get ready work: compute deferred parent children: %w", dcErr)
}
inputs.DeferredChildIDs = deferredChildIDs
}
if filter.ParentID != nil {
descendantIDs, descErr := r.getDescendantIDs(ctx, *filter.ParentID, 0)
if descErr != nil {
return nil, fmt.Errorf("get parent descendants: %w", descErr)
}
inputs.ParentDescendantIDs = descendantIDs
}
whereSQL, args, err := sqlbuild.BuildReadyWorkWhere(filter, tables, inputs)
if err != nil {
return nil, err
}
return &readyWorkPredicates{whereSQL: whereSQL, args: args}, nil
}
type deferredParentEdge struct {
depTable, issueTable, targetCol string
}
var deferredParentEdges = []deferredParentEdge{
{"dependencies", "issues", "depends_on_issue_id"},
{"dependencies", "wisps", "depends_on_wisp_id"},View on GitHub (pinned to 71377f2769)
Solutions
- Check the inner error from getDescendantIDs for the failing table or SQL issue
- Verify the ParentID exists and its dependency edges are intact
- Confirm dependencies/wisp_dependencies tables exist for this deployment mode
- If graphs are deep, raise the traversal max depth or restructure the hierarchy
Defensive patterns
Strategy: validation
Validate before calling
// confirm the parent exists before scoping ready work to it
var exists int
err := db.QueryRow("SELECT 1 FROM issues WHERE id = ?", parentID).Scan(&exists)
if errors.Is(err, sql.ErrNoRows) { return fmt.Errorf("parent %s not found", parentID) } Type guard
func isParentDescendantsError(err error) bool {
return err != nil && strings.Contains(err.Error(), "get parent descendants")
} Try / catch
ready, err := repo.GetReadyWork(ctx, filter)
if isParentDescendantsError(err) {
// drop the ParentID scope or retry after checking dependency tables
filter.ParentID = nil
ready, err = repo.GetReadyWork(ctx, filter)
} Prevention
- Validate ParentID exists before filtering ready work by it
- Keep dependencies/wisp_dependencies tables present and consistent
- Keep hierarchies shallow or raise the traversal max depth
- Retry transient failures around recursive queries
When it happens
Trigger: Calling GetReadyWork with filter.ParentID set while the recursive descendant query fails: connection error, missing dependencies/wisp_dependencies tables (after the wisp fallback also fails), or a scan/rows error inside the CTE result.
Common situations: Passing a ParentID whose dependency graph sits in tables missing from the current deployment; very deep graphs hitting max depth; transient DB errors during recursive traversal.
Related errors
- get ready work: compute deferred parent children: %w
- deferred parents: %s/%s: %w
- add dep: hierarchy check: %w
- failed to check blocker ancestry: %w
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b8c0fc25588c6d80.
Report an issue: GitHub.