gastownhall/beads · error
db: DependencySQLRepository.CycleThroughEdges (wisps): %w
Error message
db: DependencySQLRepository.CycleThroughEdges (wisps): %w
What it means
The wisps variant of CycleThroughEdges: after the core graph loads, the code also loads wisp_dependencies into the graph. A missing wisp_dependencies table is explicitly tolerated (dberrors.IsTableNotExist is skipped), so this error means the wisp table exists but loading it failed with some other error — SQL failure, connection loss, or cancellation.
Source
Thrown at internal/storage/domain/db/dependency.go:947
}
reverse := opts.Direction == domain.DepDirectionIn
out, err := issueops.GetDependencyTreeInTx(ctx, r.runner, rootID, maxDepth, opts.ShowAllPaths, reverse)
if err != nil {
return nil, fmt.Errorf("db: DependencySQLRepository.GetTree: %w", err)
}
return out, nil
}
func (r *dependencySQLRepositoryImpl) CycleThroughEdges(ctx context.Context, edges [][2]string) (string, error) {
if len(edges) == 0 {
return "", nil
}
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 {View on GitHub (pinned to 71377f2769)
Solutions
- Unwrap to find the non-table-not-exist root cause.
- Check integrity of wisp_dependencies; recreate/repair if corrupted.
- Verify connection stability and retry.
- If wisps are unused in your deployment, dropping the table cleanly restores the tolerated missing-table path.
Example fix
// before: treating every wisps failure as fatal
// after (library behavior to emulate): tolerate only table-not-exist
if err := loadWisps(ctx, graph); err != nil && !dberrors.IsTableNotExist(err) {
return "", fmt.Errorf("cycle check (wisps): %w", err)
} Defensive patterns
Strategy: type-guard
Validate before calling
if !wispTableExists(ctx, db) {
// wisps plane absent: only the core graph will be consulted
_ = dberrors.IsTableNotExist // library tolerates this case
} Type guard
func isWispTableErr(err error) bool {
return strings.Contains(err.Error(), "(wisps)") && !dberrors.IsTableNotExist(errors.Unwrap(err))
} Try / catch
edge, err := repo.CycleThroughEdges(ctx, edges)
if err != nil {
if dberrors.IsTableNotExist(errors.Unwrap(err)) {
return "", nil // missing wisp table is tolerated upstream, guard defensively
}
return fmt.Errorf("cycle check: %w", err)
} Prevention
- Do not manually delete or partially migrate wisp_dependencies — a damaged table here is fatal while a missing one is tolerated.
- Keep wisp and core schemas migrated together.
- Unwrap to distinguish tolerated missing-table from real wisp-table failures.
When it happens
Trigger: Calling CycleThroughEdges(ctx, edges) where the "wisp_dependencies" table load in AppendSchedulingGraphInTx fails with an error other than table-not-exist: corrupted table, driver error, context deadline.
Common situations: Wisp table present but damaged after an interrupted migration; permission issues on wisp_dependencies; connection dropped mid graph-build.
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.DetectCycles: %w
- db: DependencySQLRepository.DetectCycleReport: %w
- db: DependencySQLRepository.CycleThroughEdges: %w
- db: DependencySQLRepository.WispSourceIDs: %w
- db: DependencySQLRepository.HasCycle: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b620ab4e82e72a62.
Report an issue: GitHub.