{"record":{"id":"26d5b16e083b6883","repo":"gastownhall/beads","slug":"add-label-label-must-not-be-empty","errorCode":null,"errorMessage":"add label: label must not be empty","messagePattern":"add label: label must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":64,"sourceCode":"\tlabelRepo LabelSQLRepository\n}\n\nvar _ LabelUseCase = (*labelUseCaseImpl)(nil)\n\nfunc (u *labelUseCaseImpl) AddLabel(ctx context.Context, issueID, label, actor string) error {\n\treturn u.add(ctx, issueID, label, actor, false)\n}\n\nfunc (u *labelUseCaseImpl) AddWispLabel(ctx context.Context, wispID, label, actor string) error {\n\treturn u.add(ctx, wispID, label, actor, true)\n}\n\nfunc (u *labelUseCaseImpl) add(ctx context.Context, id, label, actor string, useWisp bool) error {\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"add label: id must not be empty\")\n\t}\n\tif label == \"\" {\n\t\treturn fmt.Errorf(\"add label: label must not be empty\")\n\t}\n\tif err := u.labelRepo.Insert(ctx, id, label, actor, LabelOpts{UseWispsTable: useWisp}); err != nil {\n\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\")","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L46-L82","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a non-empty label string to AddLabel/AddWispLabel.","If building labels from a list, filter empty strings before calling (AddLabels/addMany already skips empties — use it instead).","Trim user input and reject blank labels at the entry point of your tool/script.","Split comma-separated input with strings.Split and skip \"\" tokens."],"exampleFix":"// before\nfor _, l := range strings.Split(flagValue, \",\") {\n    labelUC.AddLabel(ctx, id, l, actor) // panics into error on empty token\n}\n\n// after\nfor _, l := range strings.Split(flagValue, \",\") {\n    l = strings.TrimSpace(l)\n    if l == \"\" { continue }\n    labelUC.AddLabel(ctx, id, l, actor)\n}","handlingStrategy":"validation","validationCode":"func addLabelSafe(ctx context.Context, uc LabelUseCase, id, label, actor string) error {\n    if strings.TrimSpace(label) == \"\" {\n        return errors.New(\"add label: label is required\")\n    }\n    return uc.AddLabel(ctx, id, label, actor)\n}","typeGuard":"func hasLabel(label string) bool { return strings.TrimSpace(label) != \"\" }","tryCatchPattern":"if err := uc.AddLabel(ctx, id, label, actor); err != nil {\n    if strings.Contains(err.Error(), \"label must not be empty\") {\n        return fmt.Errorf(\"skipped blank label for %s\", id)\n    }\n    return err\n}","preventionTips":["Trim and skip empty tokens when splitting label input on separators","Prefer the batch AddLabels API, which skips empty labels automatically","Reject blank labels in UI/forms before invoking the backend","Normalize label input (trim whitespace) once at the boundary"],"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"}