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
- Check the ID is non-empty before calling RemoveLabels
- Filter out records with empty IDs in bulk operations
- Fix the upstream source of the empty ID (failed lookup, missing field)
- 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
- Guard IDs before calling remove APIs
- Filter empty IDs in bulk cleanup scripts
- Capture IDs from creation/lookup results, not from user-typed input
- Use RemoveWispLabels with wisp IDs, not issue IDs
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
- add labels: id must not be empty
- set labels: id must not be empty
- get labels: id must not be empty
- db: Exists: id must not be empty
- db: LabelSQLRepository.Insert: issueID must not be empty
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/da3bd7069fb13072.
Report an issue: GitHub.