gastownhall/beads · error

set labels: add %s: %w

Error message

set labels: add %s: %w

What it means

Wraps a failure from labelRepo.Insert during the addition half of setMany (SetLabels / SetWispLabels). After removing unwanted labels, the use case inserts each newly desired label; one of those inserts failed. The failing label is named and previously applied removals/additions are not rolled back.

Source

Thrown at internal/storage/domain/label.go:176

	desired := make(map[string]bool, len(labels))
	for _, l := range labels {
		if l != "" {
			desired[l] = true
		}
	}
	existing := make(map[string]bool, len(current))
	for _, l := range current {
		existing[l] = true
		if !desired[l] {
			if err := u.labelRepo.Delete(ctx, id, l, actor, opts); err != nil {
				return fmt.Errorf("set labels: remove %s: %w", l, err)
			}
		}
	}
	for l := range desired {
		if !existing[l] {
			if err := u.labelRepo.Insert(ctx, id, l, actor, opts); err != nil {
				return fmt.Errorf("set labels: add %s: %w", l, err)
			}
		}
	}
	return nil
}

func (u *labelUseCaseImpl) GetLabels(ctx context.Context, issueID string) ([]string, error) {
	return u.list(ctx, issueID, false)
}

func (u *labelUseCaseImpl) GetWispLabels(ctx context.Context, wispID string) ([]string, error) {
	return u.list(ctx, wispID, true)
}

func (u *labelUseCaseImpl) list(ctx context.Context, id string, useWisp bool) ([]string, error) {
	if id == "" {
		return nil, fmt.Errorf("get labels: id must not be empty")
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check for duplicate labels in the desired slice and dedupe before calling
  2. Inspect the wrapped error for the storage root cause
  3. Retry SetLabels — it recomputes the diff so remaining additions get applied
  4. Serialize concurrent writers on the same issue

Example fix

// before
labels := []string{"bug", "bug", "urgent"}
store.SetLabels(ctx, id, labels, actor)
// after
slices.Sort(labels); labels = slices.Compact(labels)
return store.SetLabels(ctx, id, labels, actor)
Defensive patterns

Strategy: retry

Validate before calling

slices.Sort(labels)
labels = slices.Compact(labels)
labels = slices.DeleteFunc(labels, func(l string) bool { return l == "" })

Try / catch

if err := store.SetLabels(ctx, id, desired, actor); err != nil {
	log.Printf("set labels insert failed on %s: %v — retrying", id, err)
	time.Sleep(backoff)
	return store.SetLabels(ctx, id, desired, actor) // diff recomputed, adds retried
}

Prevention

When it happens

Trigger: SetLabels where the desired set contains labels not currently present and Insert of one fails: uniqueness constraint, driver error, concurrent write, missing parent record.

Common situations: Desired label list containing duplicates; another process adding the same label between List and Insert; Dolt/driver connectivity failures mid-operation.

Related errors


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