{"record":{"id":"c8ecef5a64109516","repo":"gastownhall/beads","slug":"remove-label-id-must-not-be-empty","errorCode":null,"errorMessage":"remove label: id must not be empty","messagePattern":"remove label: id must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":82,"sourceCode":"\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\")\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","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L64-L100","documentation":"A guard error from the label use case's remove(): it rejects removing a label when the target issue/wisp ID is empty. Called by RemoveLabel and RemoveWispLabel before any repository delete occurs.","triggerScenarios":"Calling RemoveLabel(ctx, \"\", label, actor) or RemoveWispLabel(ctx, \"\", label, actor) — the ID argument is \"\", usually from an unpopulated variable or a failed upstream lookup.","commonSituations":"Scripts where the issue key variable is unset; piping lists into a removal loop where some rows have blank IDs; tests/tools calling the Go API with a placeholder empty ID.","solutions":["Pass a resolved, non-empty issue ID to RemoveLabel/RemoveWispLabel.","Fix the upstream lookup that returned an empty ID (check errors from the fetch, not just the value).","In batch scripts, skip entries with empty IDs instead of calling remove for them.","Validate input at the CLI/tool boundary before invoking the use case."],"exampleFix":"// before\nlabelUC.RemoveLabel(ctx, os.Args[1], \"stale\", actor) // may be empty\n\n// after\nif len(os.Args) < 2 || os.Args[1] == \"\" {\n    return fmt.Errorf(\"usage: tool <issue-id> <label>\")\n}\nlabelUC.RemoveLabel(ctx, os.Args[1], \"stale\", actor)","handlingStrategy":"validation","validationCode":"func removeLabelSafe(ctx context.Context, uc LabelUseCase, id, label, actor string) error {\n    if strings.TrimSpace(id) == \"\" {\n        return errors.New(\"remove label: issue ID is required\")\n    }\n    return uc.RemoveLabel(ctx, id, label, actor)\n}","typeGuard":"func hasIssueID(id string) bool { return strings.TrimSpace(id) != \"\" }","tryCatchPattern":"if err := uc.RemoveLabel(ctx, id, label, actor); err != nil {\n    if strings.Contains(err.Error(), \"id must not be empty\") {\n        return fmt.Errorf(\"caller bug: unresolved issue ID\")\n    }\n    return err\n}","preventionTips":["Skip list entries with blank IDs before calling remove in batch scripts","Check errors (not just values) from upstream ID lookups","Validate IDs at the CLI/tool boundary","Log-and-skip rather than call remove with an unresolved ID"],"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"}