gastownhall/beads · error
descendants: hydrate wisps: %w
Error message
descendants: hydrate wisps: %w
What it means
GetDescendants wraps a failure from fetchIssuesByIDs when hydrating wisp rows matched by the descendants walk. The wisps plane is optional, so a table-not-exist error is deliberately tolerated (wispsByID stays nil); only other failures — connection drops, scan errors, hydration failures on wisp_labels/wisp_dependencies — are wrapped and returned as "descendants: hydrate wisps".
Source
Thrown at internal/storage/domain/db/issue_descendants.go:97
rows, err := r.runner.QueryContext(ctx, cte, allArgs...)
if err != nil {
return nil, fmt.Errorf("descendants: query: %w", err)
}
page, err := scanIDSrcPage(rows)
if err != nil {
return nil, fmt.Errorf("descendants: %w", err)
}
issuesByID, err := r.fetchIssuesByIDs(ctx, page.issueIDs, issuesFilterTables, filter)
if err != nil {
return nil, fmt.Errorf("descendants: hydrate issues: %w", err)
}
var wispsByID map[string]*types.Issue
if len(page.wispIDs) > 0 {
wispsByID, err = r.fetchIssuesByIDs(ctx, page.wispIDs, wispsFilterTables, filter)
if err != nil && !dberrors.IsTableNotExist(err) {
return nil, fmt.Errorf("descendants: hydrate wisps: %w", err)
}
}
return reassembleBySrc(page.ordered, issuesByID, wispsByID), nil
}
// buildDescendantsCTE walks parent-child edges AND the dotted-ID fallback the
// classic ParentID filter applies (issueops/filters.go): a row named
// <node>.<suffix> with no parent-child edge at all is a child of <node>.
// Rows carry a via marker: 'e' for edge-found, 'd' for dotted-found. Dotted
// recursion only fires from 'e' rows — a dotted node's own dotted
// descendants share its prefix and were already matched by whichever LIKE
// found it, so re-expanding them would only multiply duplicate rows.
// Filter predicates are hoisted into named matches CTEs (see predBundle) to
// dodge a dolt 2.1.6 analyzer bug.
func buildDescendantsCTE(rootID string, walkWisps bool, issuePred, wispPred predBundle) (string, []any) {
var b strings.Builder
var args []anyView on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped inner error; if it is a table-not-exist for an optional wisp table it would have been swallowed, so this indicates a different failure
- Run bd doctor to check wisp-plane table consistency (wisps, wisp_labels, wisp_dependencies)
- Retry on transient connection errors
- If the wisp plane is unusable and unwanted, re-run with SkipWisps=true to bypass wisp hydration entirely
Example fix
// before
issues, err := repo.GetDescendants(ctx, root, filter)
// after: bypass a broken optional wisp plane when only durable issues are needed
issues, err := repo.GetDescendants(ctx, root, types.IssueFilter{SkipWisps: true}) Defensive patterns
Strategy: fallback
Type guard
func isWispPlaneBroken(err error) bool {
return err != nil && strings.Contains(err.Error(), "hydrate wisps") && !dberrors.IsTableNotExist(err)
} Try / catch
issues, err := repo.GetDescendants(ctx, rootID, filter)
if isWispPlaneBroken(err) {
// degrade gracefully: durable issues only
issues, err = repo.GetDescendants(ctx, rootID, types.IssueFilter{SkipWisps: true})
} Prevention
- Treat the wisps plane as optional; always handle its absence gracefully
- Run bd doctor to keep wisps, wisp_labels, wisp_dependencies consistent
- Use SkipWisps=true when ephemeral data is not needed
- Verify full schema after clones or restores
When it happens
Trigger: Calling GetDescendants on a store where wisps exist (the walk found wisp IDs) but hydrating them fails for a reason other than the wisps/wisp_labels/wisp_dependencies tables being absent: e.g. wisp_labels is missing while wisps is present, or the connection died mid-fetch.
Common situations: Partially migrated databases where wisps exists but wisp_labels/wisp_dependencies do not — wait, the latter are tolerated only via MissingTableName on any table; a schema where wisps exists but its companion tables were dropped inconsistently; transient connection failure during hydration.
Related errors
- hydrate labels: %w
- hydrate dependencies: %w
- failed to recompute is_blocked: %w
- failed to scan federation peer: %w
- failed to scan comment: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7b7c2ba299b7e6d6.
Report an issue: GitHub.