gastownhall/beads · error
delete wisp aux rows: %w
Error message
delete wisp aux rows: %w
What it means
This error wraps failures from deleteWispAuxRowsInTx, which removes auxiliary rows associated with the wisps being deleted (side tables keyed by wisp id) after the main wisps DELETE succeeded. If aux cleanup fails, the transaction rolls back entirely so wisps are never deleted while their aux rows linger.
Source
Thrown at internal/storage/dolt/wisps.go:477
args...)
if err != nil {
return 0, fmt.Errorf("failed to batch delete wisps: %w", err)
}
rowsAffected, _ := result.RowsAffected()
// The batched wisp delete surface carries no actor, so the rows record none.
for _, id := range deletedIDs {
if err := issueops.RecordDeleteInTx(ctx, tx, id, ""); err != nil {
return 0, err
}
}
if err := issueops.DeleteWispsFromDependenciesInTx(ctx, tx, ids); err != nil {
return 0, err
}
if err := deleteWispAuxRowsInTx(ctx, tx, ids); err != nil {
return 0, fmt.Errorf("delete wisp aux rows: %w", err)
}
if err := issueops.RecomputeIsBlockedInTx(ctx, tx, affectedIssues, affectedWisps); err != nil {
return 0, fmt.Errorf("recompute is_blocked after batched wisp delete: %w", err)
}
if err := s.commitSQLTx(ctx, "commit batch wisp delete", tx); err != nil {
return 0, err
}
return int(rowsAffected), nil
}
// claimWisp atomically claims a wisp.
// Delegates SQL work to issueops.ClaimIssueInTx; no Dolt versioning needed
// since wisps live in dolt_ignored tables.
func (s *DoltStore) claimWisp(ctx context.Context, id string, actor string) error {
tx, err := s.db.BeginTx(ctx, nil)View on GitHub (pinned to 71377f2769)
Solutions
- Verify all wisp aux tables exist with the expected schema and run migrations if they don't
- Retry the delete — the transaction is atomic, so a retry after transient failure is safe
- Reduce batch size or speed up Dolt (disk, indexes on aux table id columns) if write timeouts are the cause
- Check the wrapped error chain for the specific aux table/driver error and fix it directly
Defensive patterns
Strategy: validation
Validate before calling
// Go: verify expected aux tables exist before deleting
for _, tbl := range []string{"wisp_labels", "wisp_events"} {
var one int
if err := db.QueryRowContext(ctx,
"SELECT 1 FROM information_schema.tables WHERE table_name = ?", tbl).Scan(&one); err != nil {
return fmt.Errorf("aux table %s missing: %w", tbl, err)
}
} Try / catch
_, err := store.DeleteWisps(ctx, ids)
if err != nil && strings.Contains(err.Error(), "delete wisp aux rows") {
// aux cleanup failed: whole batch rolled back; run migrations or fix schema, then retry
log.Printf("aux row cleanup failed: %v", err)
return err
} Prevention
- Run all schema migrations after upgrading bd or the storage layer
- Ensure foreign keys / cascades on aux tables are defined as expected by the schema
- Keep batches small so aux-table deletes fit within Dolt's 10s write timeout
- Index aux tables on the wisp id column to keep deletes fast
When it happens
Trigger: DeleteWisps path when the aux-row DELETE statements (e.g. labels, comments, or other wisp-keyed tables) fail: lost connection, write timeout, missing aux table, or foreign-key/constraint errors in the aux schema.
Common situations: Partially-migrated database where an aux table is missing or renamed; aux tables grown large so the delete exceeds Dolt's 10s write timeout; server connectivity loss partway through the multi-statement transaction.
Related errors
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to count issues: %w
- failed to set dolt_force_transaction_commit: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/424214e50731f86c.
Report an issue: GitHub.