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

  1. Verify all wisp aux tables exist with the expected schema and run migrations if they don't
  2. Retry the delete — the transaction is atomic, so a retry after transient failure is safe
  3. Reduce batch size or speed up Dolt (disk, indexes on aux table id columns) if write timeouts are the cause
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/424214e50731f86c. Report an issue: GitHub.