{"record":{"id":"1032101968a2ff6a","repo":"gastownhall/beads","slug":"inherit-labels-insert-s-on-s-w","errorCode":null,"errorMessage":"inherit labels: insert %s on %s: %w","messagePattern":"inherit labels: insert (.+?) on (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":253,"sourceCode":"\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 {\n\t\t\treturn inherited, fmt.Errorf(\"inherit labels: insert %s on %s: %w\", label, childID, err)\n\t\t}\n\t\tinherited = append(inherited, label)\n\t}\n\treturn inherited, nil\n}\n","sourceCodeStart":235,"sourceCodeEnd":259,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L235-L259","documentation":"Wraps a failure from labelRepo.Insert while copying one parent label onto the child during inheritance (internal/storage/domain/label.go). The message names the specific label and child ID that failed. Note the return passes back any labels already inherited, so partial progress is visible to the caller.","triggerScenarios":"Calling InheritFromParent or InheritFromWispParent where an Insert of a parent label onto childID fails: duplicate label already on child (unique constraint), database lock, context canceled mid-loop, or wisps-table insert into a missing table.","commonSituations":"Concurrent inheritance runs both inserting the same label; a unique index on (issue_id, label) rejecting a race the skipExisting list didn't cover; DB file locked by another bd process during long batch operations.","solutions":["Inspect the wrapped cause to see if it's a duplicate/unique-constraint error; if so, add the label to skipExisting or tolerate duplicates.","Check for concurrent processes performing inheritance on the same child; serialize the operation.","Verify database writability (not read-only, not locked) and retry.","Use the partially returned inherited list to resume without re-inserting succeeded labels."],"exampleFix":"// before\ninherited, err := uc.InheritFromParent(ctx, childID, parentID, actor, nil)\nif err != nil { return err } // loses partial progress\n// after\ninherited, err := uc.InheritFromParent(ctx, childID, parentID, actor, nil)\nif err != nil {\n    // inherited may be non-empty; retry with it as skipExisting\n    _, err = uc.InheritFromParent(ctx, childID, parentID, actor, inherited)\n    if err != nil { return err }\n}","handlingStrategy":"retry","validationCode":"// pre-check existing child labels to build skipExisting\nexisting, _ := uc.GetLabels(ctx, childID)\nskip := existing // pass as skipExisting","typeGuard":null,"tryCatchPattern":"inherited, err := uc.InheritFromParent(ctx, childID, parentID, actor, skip)\nif err != nil {\n    // resume with labels already applied to avoid duplicate inserts\n    _, err = uc.InheritFromParent(ctx, childID, parentID, actor, inherited)\n    if err != nil { return err }\n}","preventionTips":["Pass existing child labels as skipExisting to avoid duplicate inserts.","Serialize inheritance for the same child across processes.","Treat the partially returned inherited list as progress for resumable retries."],"tags":["go","database","labels","insert-failed"],"backgroundTag":"label-insert-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}