gastownhall/beads · error
delete: drop wisp rows: %w
Error message
delete: drop wisp rows: %w
What it means
Same final row delete as 'drop issue rows' but on the wisps table: issueRepo.DeleteByIDs with UseWispsTable:true. Failure means wisp rows could not be removed after their dependencies/labels/events were dropped; the delete aborts with this wrapped error.
Source
Thrown at internal/storage/domain/issue_delete.go:202
return result, fmt.Errorf("delete: drop labels: %w", err)
}
if _, err := u.labelRepo.DeleteAllForIDs(ctx, wispIDs, LabelOpts{UseWispsTable: true}); err != nil {
return result, fmt.Errorf("delete: drop wisp labels: %w", err)
}
if _, err := u.eventsRepo.DeleteAllForIDs(ctx, regularIDs, RecordEventOpts{}); err != nil {
return result, fmt.Errorf("delete: drop events: %w", err)
}
if _, err := u.eventsRepo.DeleteAllForIDs(ctx, wispIDs, RecordEventOpts{UseWispsTable: true}); err != nil {
return result, fmt.Errorf("delete: drop wisp events: %w", err)
}
issuesDeleted, err := u.issueRepo.DeleteByIDs(ctx, regularIDs, IssueTableOpts{})
if err != nil {
return result, fmt.Errorf("delete: drop issue rows: %w", err)
}
wispsDeleted, err := u.issueRepo.DeleteByIDs(ctx, wispIDs, IssueTableOpts{UseWispsTable: true})
if err != nil {
return result, fmt.Errorf("delete: drop wisp rows: %w", err)
}
result.DeletedCount = issuesDeleted + wispsDeleted
if params.UpdateTextReferences && len(connected) > 0 {
refs, err := u.rewriteTextReferences(ctx, allIDs, connected, connectedIsWisp, actor)
if err != nil {
return result, fmt.Errorf("delete: rewrite text references: %w", err)
}
result.ReferencesUpdated = refs
}
if err := u.issueRepo.RecomputeIsBlocked(ctx, affectedIssues, affectedWisps); err != nil {
return result, fmt.Errorf("delete: recompute is_blocked: %w", err)
}
return result, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Confirm the wisps table exists and is writable; migrate if stale.
- Retry the delete — transactional scope keeps state consistent.
- Check the wrapped cause for constraint/lock/permission details.
- Free disk space / vacuum the embedded store if resource exhaustion is indicated.
Defensive patterns
Strategy: validation
Validate before calling
if err := ctx.Err(); err != nil { return err }
exists, err := tableExists(ctx, "wisps"); if err != nil || !exists { return fmt.Errorf("wisps table missing — migrate schema") } Type guard
var dbe *storage.DBError
if errors.As(err, &dbe) { /* inspect driver cause */ } Try / catch
if err := store.DeleteWisps(ctx, ids, opts); err != nil {
if strings.Contains(err.Error(), "delete: drop wisp rows:") { /* check cause: locks, disk, perms */ }
} Prevention
- Migrate embedded stores lacking the wisps table.
- Watch disk space on the embedded Dolt data directory.
- Avoid concurrent writers to the same store.
- Use moderate batch sizes for wisp deletion.
When it happens
Trigger: DeleteWisp/DeleteWisps (or mixed sets) where the wisps table rejects the DELETE (missing table, constraint, permissions, lock) or the connection/context fails at this step.
Common situations: Older embedded DB without the wisps table; lock contention during large wisp batches; transient connection loss; disk full on the embedded Dolt store.
Related errors
- delete: drop wisp deps: %w
- hydrate neighbors (wisps): %w
- applyGraph: read existing wisp deps for %s: %w
- delete: drop deps: %w
- delete: drop sync-plane edges into deleted wisps: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/98581d177bc9ad4d.
Report an issue: GitHub.