gastownhall/beads · error
add labels: %s: %w
Error message
add labels: %s: %w
What it means
Wraps an error returned by labelRepo.Insert while adding a single label via addMany (AddLabels / AddWispLabels). The message names the label that failed so callers can tell which item in the batch broke. Underlying causes come from the storage layer (record missing, constraint violation, driver error).
Source
Thrown at internal/storage/domain/label.go:111
func (u *labelUseCaseImpl) AddLabels(ctx context.Context, issueID string, labels []string, actor string) error {
return u.addMany(ctx, issueID, labels, actor, false)
}
func (u *labelUseCaseImpl) AddWispLabels(ctx context.Context, wispID string, labels []string, actor string) error {
return u.addMany(ctx, wispID, labels, actor, true)
}
func (u *labelUseCaseImpl) addMany(ctx context.Context, id string, labels []string, actor string, useWisp bool) error {
if id == "" {
return fmt.Errorf("add labels: id must not be empty")
}
opts := LabelOpts{UseWispsTable: useWisp}
for _, label := range labels {
if label == "" {
continue
}
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}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped error (%w) for the root storage cause and fix accordingly
- Confirm the issue/wisp ID exists (GetIssue/GetLabels) before adding labels
- Check for duplicate labels if a uniqueness constraint is reported
- Verify database connectivity and that the correct database/migration state is present
Example fix
// before
if err := store.AddLabels(ctx, id, labels, actor); err != nil {
fmt.Println(err) // opaque
}
// after
if err := store.AddLabels(ctx, id, labels, actor); err != nil {
if _, gerr := store.GetIssue(ctx, id); gerr != nil {
return fmt.Errorf("issue %s missing: %w", id, gerr)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
current, err := store.GetLabels(ctx, id)
if err != nil { return err }
newLabels := slices.DeleteFunc(slices.Clone(labels), func(l string) bool {
return l == "" || slices.Contains(current, l)
}) Try / catch
if err := store.AddLabels(ctx, id, labels, actor); err != nil {
var label string
if _, perr := fmt.Sscanf(err.Error(), "add labels: %s", &label); perr == nil {
log.Printf("failed adding label %q to %s: %v", label, id, err)
} else {
return err
}
} Prevention
- Confirm the issue exists before adding labels
- Dedupe and drop empty labels before calling
- Treat label adds as idempotent (skip already-present labels)
- Keep database connectivity and migrations healthy
When it happens
Trigger: AddLabels or AddWispLabels called with a non-empty label where the labelRepo.Insert call fails: the issue/wisp ID does not exist in the table, a database constraint fires, or the storage driver errors.
Common situations: Adding labels to an issue ID that was deleted or from another database; duplicated label violating a uniqueness constraint; Dolt/driver connection problems; using a wisp ID with the non-wisp API.
Related errors
- set labels: add %s: %w
- add label '%s' on %s: %w
- add label '%s' on %s: %w
- read labels for %s: %w
- copy label %q for %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/83b3d2a13f2bff9e.
Report an issue: GitHub.