gastownhall/beads · error
previewDelete: load wisps: %w
Error message
previewDelete: load wisps: %w
What it means
This error wraps a failure from issueRepo.GetByIDs with UseWispsTable=true in previewDelete. A missing wisps table is deliberately tolerated (IsTableNotExist is ignored) because a database may never have contained wisps; any other failure aborts the preview.
Source
Thrown at internal/storage/domain/issue_delete.go:292
preview := DeletePreview{
Issues: map[string]*types.Issue{},
ConnectedIssues: map[string]*types.Issue{},
DepRecords: map[string][]*types.Dependency{},
}
if len(ids) == 0 {
return preview, nil
}
fromIssues, err := u.issueRepo.GetByIDs(ctx, ids, IssueTableOpts{})
if err != nil {
return preview, fmt.Errorf("previewDelete: load issues: %w", err)
}
for _, iss := range fromIssues {
preview.Issues[iss.ID] = iss
}
fromWisps, err := u.issueRepo.GetByIDs(ctx, ids, IssueTableOpts{UseWispsTable: true})
if err != nil && !dberrors.IsTableNotExist(err) {
return preview, fmt.Errorf("previewDelete: load wisps: %w", err)
}
for _, iss := range fromWisps {
preview.Issues[iss.ID] = iss
}
for _, id := range ids {
if _, ok := preview.Issues[id]; !ok {
preview.NotFound = append(preview.NotFound, id)
}
}
depRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionOut})
if err != nil {
return preview, fmt.Errorf("previewDelete: list deps: %w", err)
}
for id, deps := range depRes.Outgoing {
preview.DepRecords[id] = deps
}View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped cause; if it is table-not-exist the code already tolerates it, so a surfaced error means a different failure.
- Restore DB connectivity and re-run the preview.
- Verify wisps-table schema matches the installed beads version.
- Chunk very large id lists.
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure wisps schema is present or intentionally absent:
if err := migrate(ctx); err != nil {
return fmt.Errorf("wisps schema check failed: %w", err)
} Type guard
if dberrors.IsTableNotExist(errors.Unwrap(err)) {
return nil // tolerated: no wisps in this database
}
var dbErr *dberrors.DBError
if errors.As(err, &dbErr) {
// real driver failure
} Try / catch
preview, err := uc.PreviewDeleteWisp(ctx, ids)
if err != nil && strings.Contains(err.Error(), "previewDelete: load wisps") {
if !dberrors.IsTableNotExist(errors.Unwrap(err)) {
return fmt.Errorf("wisp preview failed: %w", err)
}
} Prevention
- Keep wisps tables migrated or confirm wisps are unused
- Retry transient failures — preview is read-only
- Avoid concurrent wisp writers during previews
- Chunk oversized id lists
When it happens
Trigger: PreviewDelete/PreviewDeleteWisp when the wisps table exists but the bulk fetch of wisp rows by id fails for a non-table-not-exist reason: connection drop, timeout, scan error.
Common situations: Wisps table locked by another writer; driver/schema drift after an upgrade; transient DB outage during a delete dry-run.
Related errors
- previewDelete: list wisp deps: %w
- wisp plane membership: %w
- delete: list wisp dependents: %w
- previewDelete: load issues: %w
- previewDelete: list deps: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f40eaf08acb32e80.
Report an issue: GitHub.