gastownhall/beads · error

failed to batch delete wisps: %w

Error message

failed to batch delete wisps: %w

What it means

During deleteIssues, when active wisp ids are found, deleteWispBatch removes them in bulk; any error from that batch delete is wrapped with this message. The delete transaction aborts and the caller receives the wrapped cause.

Source

Thrown at internal/storage/dolt/issues.go:729

	}

	// Route wisp IDs to wisp deletion; process regular IDs in batch below.
	// DoltStore uses its own batch wisp deletion (separate transactions per batch
	// to avoid write timeout on large sets — see bd-2ehd, ff-tqm).
	ephIDs, regularIDs := s.partitionByWispStatus(ctx, ids)
	wispDeleteCount := 0
	if len(ephIDs) > 0 {
		var activeWispIDs []string
		for _, eid := range ephIDs {
			if s.isActiveWisp(ctx, eid) {
				activeWispIDs = append(activeWispIDs, eid)
			}
		}
		wispDeleteCount = len(activeWispIDs)
		if !dryRun && len(activeWispIDs) > 0 {
			deleted, err := s.deleteWispBatch(ctx, activeWispIDs)
			if err != nil {
				return nil, fmt.Errorf("failed to batch delete wisps: %w", err)
			}
			wispDeleteCount = deleted
		}
	}
	ids = regularIDs
	if len(ids) == 0 {
		return &types.DeleteIssuesResult{DeletedCount: wispDeleteCount}, nil
	}

	var result *types.DeleteIssuesResult
	if err := s.withWriteTx(ctx, func(tx *sql.Tx) error {
		r, err := issueops.DeleteIssuesInTx(ctx, tx, ids, cascade, force, dryRun)
		if err != nil {
			result = r
			return err
		}
		result = r
		if dryRun {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped cause (%w) to identify the SQL/storage failure and address it (connectivity, permissions, conflict)
  2. Re-run the delete; wisp deletes are idempotent for already-removed ids
  3. Retry with a smaller batch of ids to isolate a problematic row
  4. Use --dry-run first to confirm which wisps will be deleted before the real delete
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: list what would be deleted
await bdDelete({ dryRun: true, ids });

Try / catch

try {
  await bdDelete({ ids });
} catch (e) {
  if (String(e.message).includes("failed to batch delete wisps")) {
    // inspect e.cause, retry in smaller batches
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a bulk delete that includes active wisps with dryRun=false where deleteWispBatch fails — e.g. SQL error, transaction conflict, or storage backend unavailable.

Common situations: Cleanup jobs deleting stale wisps while the Dolt server is unhealthy; concurrent modifications to the same wisps causing optimistic-merge conflicts; permission/connection problems in server mode.

Related errors


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