gastownhall/beads · error
descendants: wisp_dependencies probe: %w
Error message
descendants: wisp_dependencies probe: %w
What it means
Wraps a failure from optionalTableExists probing the wisp_dependencies table during GetDescendants. The probe runs 'SELECT 1 FROM wisp_dependencies LIMIT 1' and only treats table-not-exist as a clean 'false'; any other probe error (connection, permissions, driver malfunction) is wrapped here and aborts the descendants walk. This decides whether wisp dependencies can be traversed.
Source
Thrown at internal/storage/domain/db/issue_descendants.go:51
snippet: fmt.Sprintf(" AND %s.id IN (SELECT id FROM %s)", alias, cteName),
args: args,
}
}
func (r *issueSQLRepositoryImpl) GetDescendants(ctx context.Context, rootID string, filter types.IssueFilter) ([]*types.Issue, error) {
levelFilter := filter
levelFilter.ParentID = nil
levelFilter.Limit = 0
levelFilter.Offset = 0
issueWhereClauses, issueArgs, err := buildIssueFilterClauses("", levelFilter, issuesFilterTables)
if err != nil {
return nil, fmt.Errorf("descendants: issues filter: %w", err)
}
wispDepsExist, err := r.optionalTableExists(ctx, "wisp_dependencies")
if err != nil {
return nil, fmt.Errorf("descendants: wisp_dependencies probe: %w", err)
}
walkWisps := wispDepsExist && !filter.SkipWisps
if walkWisps {
empty, probeErr := r.wispsTableEmptyOrMissing(ctx)
if probeErr != nil {
return nil, fmt.Errorf("descendants: wisps table probe: %w", probeErr)
}
walkWisps = !empty
}
var wispWhereClauses []string
var wispArgs []any
if walkWisps {
wispWhereClauses, wispArgs, err = buildIssueFilterClauses("", levelFilter, wispsFilterTables)
if err != nil {
return nil, fmt.Errorf("descendants: wisps filter: %w", err)
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped cause; if it's a permissions error, grant SELECT on wisp_dependencies or fix the connection user.
- Upgrade the storage/dberrors layer if the server's table-not-exist error shape isn't recognized (falls through as a hard error).
- Check connectivity and retry — the probe is read-only and cheap.
- If wisps are unused in your deployment, set filter.SkipWisps to bypass wisp traversal entirely.
Example fix
// before deps, err := repo.GetDescendants(ctx, id, filter) // hard-fails on probe error // after filter.SkipWisps = true // deployment has no wisp tables / no perms deps, err := repo.GetDescendants(ctx, id, filter)
Defensive patterns
Strategy: fallback
Validate before calling
// pre-probe permissions with the same identity the app uses
rows, err := db.Query("SELECT 1 FROM wisp_dependencies LIMIT 1")
if err != nil && !isTableNotExist(err) { log.Printf("wisp probe unhealthy: %v", err) }
if rows != nil { rows.Close() } Try / catch
deps, err := repo.GetDescendants(ctx, id, filter)
if err != nil {
if strings.Contains(err.Error(), "wisp_dependencies probe") {
filter.SkipWisps = true // degrade: walk issues only
return repo.GetDescendants(ctx, id, filter)
}
return err
} Prevention
- Grant the app DB user SELECT on wisp_dependencies in wisp-enabled deployments.
- Set filter.SkipWisps where wisps are not used to skip the probe path entirely.
- Keep dberrors/db driver versions aligned with the server so table-not-exist is recognized.
- Health-check optional tables at startup rather than mid-request.
When it happens
Trigger: Calling GetDescendants when the wisp_dependencies probe fails with something other than sql.ErrNoRows or a recognized table-not-exist error: connection failure, permission denied on the table, corrupted catalog, or context cancellation.
Common situations: DB user lacking SELECT on wisp_dependencies, connection dropped between queries, a Dolt server version whose not-exist error isn't recognized by dberrors.IsTableNotExist (version drift), or cancellation timeouts.
Related errors
- scan wisp dependent: %w
- failed to recompute is_blocked: %w
- failed to scan federation peer: %w
- failed to scan comment: %w
- failed to initialize schema: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4fa007349ed8314b.
Report an issue: GitHub.