gastownhall/beads · error
db: DependencySQLRepository.WispSourceIDs: %w
Error message
db: DependencySQLRepository.WispSourceIDs: %w
What it means
WispSourceIDs calls issueops.WispIDSetInTx to classify which of the given IDs live in the wisp plane, in one scoped query. Like the delete/count paths, a missing wisps table inside WispIDSetInTx is treated as 'no wisps' rather than an error, so this wrapper means a genuine failure occurred: SQL error, connection loss, or scan failure.
Source
Thrown at internal/storage/domain/db/dependency.go:959
}
graph := make(map[string][]string)
if err := issueops.AppendSchedulingGraphInTx(ctx, r.runner, []string{"dependencies"}, graph); err != nil {
return "", fmt.Errorf("db: DependencySQLRepository.CycleThroughEdges: %w", err)
}
if err := issueops.AppendSchedulingGraphInTx(ctx, r.runner, []string{"wisp_dependencies"}, graph); err != nil && !dberrors.IsTableNotExist(err) {
return "", fmt.Errorf("db: DependencySQLRepository.CycleThroughEdges (wisps): %w", err)
}
return issueops.CycleThroughEdgesInGraph(graph, edges), nil
}
// WispSourceIDs classifies a batch of ids by plane in one scoped query. It is
// the proxied twin of the in-tx probe the store-backed dependency editor runs,
// and shares its implementation so the two answer the same question — down to
// treating a missing wisps table as "no wisps" rather than an error.
func (r *dependencySQLRepositoryImpl) WispSourceIDs(ctx context.Context, ids []string) (map[string]struct{}, error) {
set, err := issueops.WispIDSetInTx(ctx, r.runner, ids)
if err != nil {
return nil, fmt.Errorf("db: DependencySQLRepository.WispSourceIDs: %w", err)
}
return set, nil
}
func (r *dependencySQLRepositoryImpl) GetDependencyRecordsForIssues(ctx context.Context, issueIDs []string) (map[string][]*types.Dependency, error) {
if len(issueIDs) == 0 {
return map[string][]*types.Dependency{}, nil
}
out, err := issueops.GetDependencyRecordsForIssuesInTx(ctx, r.runner, issueIDs)
if err != nil {
return nil, fmt.Errorf("db: DependencySQLRepository.GetDependencyRecordsForIssues: %w", err)
}
return out, nil
}
func (r *dependencySQLRepositoryImpl) GetWispDependencyRecordsForIDs(ctx context.Context, wispIDs []string) (map[string][]*types.Dependency, error) {
if len(wispIDs) == 0 {
return map[string][]*types.Dependency{}, nilView on GitHub (pinned to 71377f2769)
Solutions
- Unwrap to see the root driver/SQL error.
- Verify wisp tables exist and are healthy (run migrations/repair).
- Retry transient failures with a fresh context.
- Ensure IDs are valid non-empty strings; empty input short-circuits at the caller, not here.
Example fix
// before
set, err := repo.WispSourceIDs(ctx, ids)
if err != nil { panic(err) }
// after: degrade gracefully when wisps are unavailable
set, err := repo.WispSourceIDs(ctx, ids)
if err != nil {
log.Warn("wisp probe failed, assuming none", "err", err)
set = map[string]struct{}{}
} Defensive patterns
Strategy: fallback
Validate before calling
if len(ids) == 0 {
return map[string]struct{}{} // skip the DB probe entirely
} Type guard
func emptyIDs(ids []string) bool { return len(ids) == 0 } Try / catch
set, err := repo.WispSourceIDs(ctx, ids)
if err != nil {
// degrade: assume no wisps rather than failing the edit
log.Warn("wisp classification failed", "err", err)
set = map[string]struct{}{}
} Prevention
- Pass an empty slice early-exit instead of probing with no IDs.
- Degrade gracefully when the wisp plane is unavailable — callers of this probe usually can.
- Keep wisp tables healthy; only a missing table is tolerated as 'no wisps'.
When it happens
Trigger: Calling WispSourceIDs(ctx, ids) with a non-empty ID list where WispIDSetInTx errors other than missing-table: corrupted wisp tables, driver failure, context cancellation.
Common situations: Dependency editors deciding whether an ID is a wisp before editing, against an unhealthy database; permission errors on wisp tables; timeouts under heavy load.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- db: DependencySQLRepository.CycleThroughEdges (wisps): %w
- delete: classify planes: %w
- db: DependencySQLRepository.IsBlocked %s: %w
- db: DependencySQLRepository.DetectCycles: %w
- db: DependencySQLRepository.DetectCycleReport: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ac7147549cafc28d.
Report an issue: GitHub.