gastownhall/beads · error

add label: label must not be empty

Error message

add label: label must not be empty

What it means

A guard error from label add(): it rejects an empty label string. AddLabel/AddWispLabel validate arguments before touching the repository, so an empty label never reaches the database.

Source

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

	labelRepo LabelSQLRepository
}

var _ LabelUseCase = (*labelUseCaseImpl)(nil)

func (u *labelUseCaseImpl) AddLabel(ctx context.Context, issueID, label, actor string) error {
	return u.add(ctx, issueID, label, actor, false)
}

func (u *labelUseCaseImpl) AddWispLabel(ctx context.Context, wispID, label, actor string) error {
	return u.add(ctx, wispID, label, actor, true)
}

func (u *labelUseCaseImpl) add(ctx context.Context, id, label, actor string, useWisp bool) error {
	if id == "" {
		return fmt.Errorf("add label: id must not be empty")
	}
	if label == "" {
		return fmt.Errorf("add label: label must not be empty")
	}
	if err := u.labelRepo.Insert(ctx, id, label, actor, LabelOpts{UseWispsTable: useWisp}); err != nil {
		return fmt.Errorf("add label %s/%s: %w", id, label, err)
	}
	return nil
}

func (u *labelUseCaseImpl) RemoveLabel(ctx context.Context, issueID, label, actor string) error {
	return u.remove(ctx, issueID, label, actor, false)
}

func (u *labelUseCaseImpl) RemoveWispLabel(ctx context.Context, wispID, label, actor string) error {
	return u.remove(ctx, wispID, label, actor, true)
}

func (u *labelUseCaseImpl) remove(ctx context.Context, id, label, actor string, useWisp bool) error {
	if id == "" {
		return fmt.Errorf("remove label: id must not be empty")

View on GitHub (pinned to 71377f2769)

Solutions

  1. Pass a non-empty label string to AddLabel/AddWispLabel.
  2. If building labels from a list, filter empty strings before calling (AddLabels/addMany already skips empties — use it instead).
  3. Trim user input and reject blank labels at the entry point of your tool/script.
  4. Split comma-separated input with strings.Split and skip "" tokens.

Example fix

// before
for _, l := range strings.Split(flagValue, ",") {
    labelUC.AddLabel(ctx, id, l, actor) // panics into error on empty token
}

// after
for _, l := range strings.Split(flagValue, ",") {
    l = strings.TrimSpace(l)
    if l == "" { continue }
    labelUC.AddLabel(ctx, id, l, actor)
}
Defensive patterns

Strategy: validation

Validate before calling

func addLabelSafe(ctx context.Context, uc LabelUseCase, id, label, actor string) error {
    if strings.TrimSpace(label) == "" {
        return errors.New("add label: label is required")
    }
    return uc.AddLabel(ctx, id, label, actor)
}

Type guard

func hasLabel(label string) bool { return strings.TrimSpace(label) != "" }

Try / catch

if err := uc.AddLabel(ctx, id, label, actor); err != nil {
    if strings.Contains(err.Error(), "label must not be empty") {
        return fmt.Errorf("skipped blank label for %s", id)
    }
    return err
}

Prevention

When it happens

Trigger: Calling AddLabel(ctx, id, "", actor) or AddWispLabel(ctx, id, "", actor) — e.g. an empty label literal, or a label variable derived from input that was blank.

Common situations: CLI flags like --label "" or a trailing separator in a comma-separated list ("p1,,p2") producing an empty token; config files with an empty label key; programmatic callers passing uninitialized label variables.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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