gastownhall/beads · error

remove labels: id must not be empty

Error message

remove labels: id must not be empty

What it means

Thrown by removeMany (RemoveLabels / RemoveWispLabels) when the issue or wisp ID is an empty string. Like the add/remove/set family, the ID is validated before touching the repository since deleting labels for an unnamed record is meaningless. Pure input validation.

Source

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

		}
		if err := u.labelRepo.Insert(ctx, id, label, actor, opts); err != nil {
			return fmt.Errorf("add labels: %s: %w", label, err)
		}
	}
	return nil
}

func (u *labelUseCaseImpl) RemoveLabels(ctx context.Context, issueID string, labels []string, actor string) error {
	return u.removeMany(ctx, issueID, labels, actor, false)
}

func (u *labelUseCaseImpl) RemoveWispLabels(ctx context.Context, wispID string, labels []string, actor string) error {
	return u.removeMany(ctx, wispID, labels, actor, true)
}

func (u *labelUseCaseImpl) removeMany(ctx context.Context, id string, labels []string, actor string, useWisp bool) error {
	if id == "" {
		return fmt.Errorf("remove labels: id must not be empty")
	}
	opts := LabelOpts{UseWispsTable: useWisp}
	for _, label := range labels {
		if label == "" {
			continue
		}
		if err := u.labelRepo.Delete(ctx, id, label, actor, opts); err != nil {
			return fmt.Errorf("remove labels: %s: %w", label, err)
		}
	}
	return nil
}

func (u *labelUseCaseImpl) SetLabels(ctx context.Context, issueID string, labels []string, actor string) error {
	return u.setMany(ctx, issueID, labels, actor, false)
}

func (u *labelUseCaseImpl) SetWispLabels(ctx context.Context, wispID string, labels []string, actor string) error {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the ID is non-empty before calling RemoveLabels
  2. Filter out records with empty IDs in bulk operations
  3. Fix the upstream source of the empty ID (failed lookup, missing field)
  4. Ensure you pass the wisp ID to RemoveWispLabels, not an empty issue ID

Example fix

// before
store.RemoveLabels(ctx, id, labels, actor) // id may be ""
// after
if id == "" {
	return fmt.Errorf("cannot remove labels: no issue id")
}
store.RemoveLabels(ctx, id, labels, actor)
Defensive patterns

Strategy: validation

Validate before calling

if id == "" {
	return fmt.Errorf("cannot remove labels: issue id is empty")
}
if err := store.RemoveLabels(ctx, id, labels, actor); err != nil { ... }

Prevention

When it happens

Trigger: RemoveLabels(ctx, "", labels, actor) or RemoveWispLabels(ctx, "", labels, actor); an ID variable empty due to a failed lookup, empty CLI argument, or unset struct field.

Common situations: Bulk scripts iterating records where some IDs came back empty; cleanup jobs reading IDs from CSV/JSON with missing fields; using a variable set from a failed parse.

Related errors


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