gastownhall/beads · error

delete: count labels: %w

Error message

delete: count labels: %w

What it means

deleteMany wraps errors from labelRepo.CountAllForIDs on the regular-issues table when pre-deleting label counts are gathered for the result stats. The 'delete: count labels:' prefix marks the failure; the underlying repository error is preserved via %w. No deletion has occurred yet.

Source

Thrown at internal/storage/domain/issue_delete.go:125

	}
	if len(allIDs) == 0 {
		return DeleteIssuesResult{}, nil
	}

	wispIDs, regularIDs, err := u.issueRepo.PartitionWispIDs(ctx, allIDs)
	if err != nil {
		return DeleteIssuesResult{}, fmt.Errorf("delete: partition: %w", err)
	}

	depCount, err := u.countDeletedDependencies(ctx, allIDs)
	if err != nil {
		return DeleteIssuesResult{}, err
	}
	result.DependenciesCount = depCount

	labelIssue, err := u.labelRepo.CountAllForIDs(ctx, regularIDs, LabelOpts{})
	if err != nil {
		return DeleteIssuesResult{}, fmt.Errorf("delete: count labels: %w", err)
	}
	labelWisp, err := u.labelRepo.CountAllForIDs(ctx, wispIDs, LabelOpts{UseWispsTable: true})
	if err != nil {
		return DeleteIssuesResult{}, fmt.Errorf("delete: count wisp labels: %w", err)
	}
	result.LabelsCount = labelIssue + labelWisp

	evIssue, err := u.eventsRepo.CountAllForIDs(ctx, regularIDs, RecordEventOpts{})
	if err != nil {
		return DeleteIssuesResult{}, fmt.Errorf("delete: count events: %w", err)
	}
	evWisp, err := u.eventsRepo.CountAllForIDs(ctx, wispIDs, RecordEventOpts{UseWispsTable: true})
	if err != nil {
		return DeleteIssuesResult{}, fmt.Errorf("delete: count wisp events: %w", err)
	}
	result.EventsCount = evIssue + evWisp

	if params.DryRun {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the error to see the CountAllForIDs driver failure
  2. Verify the labels table exists and Dolt is healthy
  3. Retry the delete; deletion has not started, so it is safe
  4. If stats are non-essential, consider whether the library offers a mode that tolerates count failures

Example fix

// before
res, err := uc.DeleteIssues(ctx, ids, actor)
// after
if err != nil {
	if strings.Contains(err.Error(), "count labels") {
		log.Printf("label count failed, nothing deleted: %v", err)
	}
	return err
}
Defensive patterns

Strategy: retry

Validate before calling

if err := pingDolt(ctx); err != nil {
	return fmt.Errorf("storage unavailable, skipping delete: %w", err)
}

Try / catch

res, err := uc.DeleteIssues(ctx, ids, actor)
if err != nil && strings.Contains(err.Error(), "count labels") {
	// stats phase failed; nothing deleted — retry after health check
	return retryDelete(ctx, ids)
}

Prevention

When it happens

Trigger: DeleteIssue/DeleteIssues/DeleteWisps/DeleteWisp reaching the stats-counting phase when CountAllForIDs(ctx, regularIDs, LabelOpts{}) fails — DB error, missing labels table, or connection loss.

Common situations: Deletes with result-stat collection running against a Dolt instance with schema drift or an in-progress migration; connection pool exhaustion during bulk deletes.

Related errors


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