{"record":{"id":"3533c78b711386df","repo":"gastownhall/beads","slug":"remove-label-label-must-not-be-empty","errorCode":null,"errorMessage":"remove label: label must not be empty","messagePattern":"remove label: label must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":85,"sourceCode":"\t\treturn fmt.Errorf(\"add label %s/%s: %w\", id, label, err)\n\t}\n\treturn nil\n}\n\nfunc (u *labelUseCaseImpl) RemoveLabel(ctx context.Context, issueID, label, actor string) error {\n\treturn u.remove(ctx, issueID, label, actor, false)\n}\n\nfunc (u *labelUseCaseImpl) RemoveWispLabel(ctx context.Context, wispID, label, actor string) error {\n\treturn u.remove(ctx, wispID, label, actor, true)\n}\n\nfunc (u *labelUseCaseImpl) remove(ctx context.Context, id, label, actor string, useWisp bool) error {\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"remove label: id must not be empty\")\n\t}\n\tif label == \"\" {\n\t\treturn fmt.Errorf(\"remove label: label must not be empty\")\n\t}\n\tif err := u.labelRepo.Delete(ctx, id, label, actor, LabelOpts{UseWispsTable: useWisp}); err != nil {\n\t\treturn fmt.Errorf(\"remove label %s/%s: %w\", id, label, err)\n\t}\n\treturn nil\n}\n\nfunc (u *labelUseCaseImpl) AddLabels(ctx context.Context, issueID string, labels []string, actor string) error {\n\treturn u.addMany(ctx, issueID, labels, actor, false)\n}\n\nfunc (u *labelUseCaseImpl) AddWispLabels(ctx context.Context, wispID string, labels []string, actor string) error {\n\treturn u.addMany(ctx, wispID, labels, actor, true)\n}\n\nfunc (u *labelUseCaseImpl) addMany(ctx context.Context, id string, labels []string, actor string, useWisp bool) error {\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"add labels: id must not be empty\")","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L67-L103","documentation":"A guard error from label remove(): it rejects an empty label string. RemoveLabel/RemoveWispLabel validate arguments before calling labelRepo.Delete, so an empty label never reaches storage.","triggerScenarios":"Calling RemoveLabel(ctx, id, \"\", actor) or RemoveWispLabel(ctx, id, \"\", actor) — an empty label literal or a blank token produced by splitting/parsing label input.","commonSituations":"Comma-separated label lists with empty entries (\"p1,,p2\"); shell variables expanding to nothing; UI/tool code passing an unselected (empty) label value.","solutions":["Pass a non-empty label string to RemoveLabel/RemoveWispLabel.","Filter empty strings out of label lists before removal, or use RemoveLabels which handles lists.","Trim and validate user-provided label input at the entry point.","If the label is optional in your flow, skip the remove call when it's blank."],"exampleFix":"// before\nlabelUC.RemoveLabel(ctx, id, cfg.Label, actor) // cfg.Label may be \"\"\n\n// after\nif cfg.Label != \"\" {\n    labelUC.RemoveLabel(ctx, id, cfg.Label, actor)\n}","handlingStrategy":"validation","validationCode":"func removeLabelSafe(ctx context.Context, uc LabelUseCase, id, label, actor string) error {\n    if strings.TrimSpace(label) == \"\" {\n        return nil // nothing to remove; treat as no-op\n    }\n    return uc.RemoveLabel(ctx, id, label, actor)\n}","typeGuard":"func hasLabel(label string) bool { return strings.TrimSpace(label) != \"\" }","tryCatchPattern":"if err := uc.RemoveLabel(ctx, id, label, actor); err != nil {\n    if strings.Contains(err.Error(), \"label must not be empty\") {\n        return nil // treat blank label as a no-op\n    }\n    return err\n}","preventionTips":["Filter empty strings from label lists before removal","Use the batch RemoveLabels API for list inputs","Trim user input before passing label values","Treat a blank optional label as a no-op in your own layer"],"tags":["validation","labels","argument-error"],"backgroundTag":"missing-required-argument","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}