{"record":{"id":"fb4baa3c482a90a7","repo":"gastownhall/beads","slug":"inherit-labels-parentid-must-not-be-empty","errorCode":null,"errorMessage":"inherit labels: parentID must not be empty","messagePattern":"inherit labels: parentID must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":234,"sourceCode":"\t\treturn nil, fmt.Errorf(\"get labels bulk: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *labelUseCaseImpl) InheritFromParent(ctx context.Context, childID, parentID, actor string, skipExisting []string) ([]string, error) {\n\treturn u.inherit(ctx, childID, parentID, actor, skipExisting, false)\n}\n\nfunc (u *labelUseCaseImpl) InheritFromWispParent(ctx context.Context, childWispID, parentWispID, actor string, skipExisting []string) ([]string, error) {\n\treturn u.inherit(ctx, childWispID, parentWispID, actor, skipExisting, true)\n}\n\nfunc (u *labelUseCaseImpl) inherit(ctx context.Context, childID, parentID, actor string, skipExisting []string, useWisp bool) ([]string, error) {\n\tif childID == \"\" {\n\t\treturn nil, fmt.Errorf(\"inherit labels: childID must not be empty\")\n\t}\n\tif parentID == \"\" {\n\t\treturn nil, fmt.Errorf(\"inherit labels: parentID must not be empty\")\n\t}\n\tparentLabels, err := u.labelRepo.List(ctx, parentID, LabelOpts{UseWispsTable: useWisp})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"inherit labels: list parent %s: %w\", parentID, err)\n\t}\n\tif len(parentLabels) == 0 {\n\t\treturn nil, nil\n\t}\n\tskip := make(map[string]bool, len(skipExisting))\n\tfor _, s := range skipExisting {\n\t\tskip[s] = true\n\t}\n\tvar inherited []string\n\tfor _, label := range parentLabels {\n\t\tif skip[label] {\n\t\t\tcontinue\n\t\t}\n\t\tif err := u.labelRepo.Insert(ctx, childID, label, actor, LabelOpts{UseWispsTable: useWisp}); err != nil {","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L216-L252","documentation":"A guard error thrown by the label inheritance use-case (inherit in internal/storage/domain/label.go) when the parent issue ID is an empty string. The parent's labels are the source for inheritance, so a parent ID is required. Raised before any repository access.","triggerScenarios":"Calling InheritFromParent(ctx, childID, \"\", actor, skipExisting) or InheritFromWispParent(ctx, childWispID, \"\", actor, skipExisting) — the parent reference was never resolved or an empty parent struct field was passed.","commonSituations":"A dependency lookup returned no parent (e.g., issue has no 'blocks/blocked-by' or parent relationship) and the code passed the zero-value ID; JSON configs missing the parent field; wisps whose parent pointer was never set.","solutions":["Resolve and verify the parent issue ID before calling inheritance (e.g., from the issue's dependency or parent field).","If the issue genuinely has no parent, skip inheritance for it instead of calling with an empty ID.","Validate parentID non-empty at the call site and return a clearer domain error there."],"exampleFix":"// before\nvar parentID string // never assigned\nuc.InheritFromParent(ctx, childID, parentID, actor, nil)\n// after\nif parentID == \"\" { return nil } // no parent: nothing to inherit\nuc.InheritFromParent(ctx, childID, parentID, actor, nil)","handlingStrategy":"validation","validationCode":"if parentID == \"\" { return nil } // no parent: skip inheritance","typeGuard":"func hasParentID(parentID string) bool { return strings.TrimSpace(parentID) != \"\" }","tryCatchPattern":null,"preventionTips":["Resolve the parent relationship explicitly; skip inheritance when there is none.","Never pass zero-value struct fields as IDs.","Validate parent references after deserializing configs/JSON."],"tags":["go","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"}