{"record":{"id":"8757865aea2f0a75","repo":"gastownhall/beads","slug":"get-labels-s-w","errorCode":null,"errorMessage":"get labels %s: %w","messagePattern":"get labels (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/label.go","lineNumber":197,"sourceCode":"\t}\n\treturn nil\n}\n\nfunc (u *labelUseCaseImpl) GetLabels(ctx context.Context, issueID string) ([]string, error) {\n\treturn u.list(ctx, issueID, false)\n}\n\nfunc (u *labelUseCaseImpl) GetWispLabels(ctx context.Context, wispID string) ([]string, error) {\n\treturn u.list(ctx, wispID, true)\n}\n\nfunc (u *labelUseCaseImpl) list(ctx context.Context, id string, useWisp bool) ([]string, error) {\n\tif id == \"\" {\n\t\treturn nil, fmt.Errorf(\"get labels: id must not be empty\")\n\t}\n\tout, err := u.labelRepo.List(ctx, id, LabelOpts{UseWispsTable: useWisp})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get labels %s: %w\", id, err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *labelUseCaseImpl) GetLabelsForIssues(ctx context.Context, issueIDs []string) (map[string][]string, error) {\n\treturn u.listBulk(ctx, issueIDs, false)\n}\n\nfunc (u *labelUseCaseImpl) GetLabelsForWisps(ctx context.Context, wispIDs []string) (map[string][]string, error) {\n\treturn u.listBulk(ctx, wispIDs, true)\n}\n\nfunc (u *labelUseCaseImpl) listBulk(ctx context.Context, ids []string, useWisp bool) (map[string][]string, error) {\n\tif len(ids) == 0 {\n\t\treturn map[string][]string{}, nil\n\t}\n\tout, err := u.labelRepo.ListByIssueIDs(ctx, ids, LabelOpts{UseWispsTable: useWisp})\n\tif err != nil {","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/label.go#L179-L215","documentation":"Wraps a failure from labelRepo.List in list (GetLabels / GetWispLabels). The message includes the ID being queried plus the underlying storage error. The read failed so no labels are returned; this never means the ID was empty (that is the sibling 'id must not be empty' error).","triggerScenarios":"GetLabels/GetWispLabels on a non-empty ID where labelRepo.List fails: database unavailable, driver error, table missing due to skipped migration, transaction conflict.","commonSituations":"Dolt remote not pulled / stale database; running commands before migrations created labels tables; transient connectivity loss; querying an ID in the wrong database.","solutions":["Inspect the wrapped error for the storage root cause","Verify connectivity and migration state of the database","Sync the database if the record may not exist locally yet (bd dolt pull)","Retry — a pure read is safe to retry after transient failures"],"exampleFix":"// before\nlabels, err := store.GetLabels(ctx, id)\nif err != nil { log.Fatal(err) }\n// after\nlabels, err := store.GetLabels(ctx, id)\nif err != nil {\n\treturn fmt.Errorf(\"get labels for %s: %w\", id, err) // id included in message already\n}","handlingStrategy":"retry","validationCode":"// Ensure ID non-empty first; then the error only means storage/read failure.\nif id == \"\" { return nil, fmt.Errorf(\"empty id\") }","typeGuard":null,"tryCatchPattern":"labels, err := store.GetLabels(ctx, id)\nif err != nil {\n\ttime.Sleep(200 * time.Millisecond)\n\tlabels, err = store.GetLabels(ctx, id) // read is safe to retry\n\tif err != nil { return nil, fmt.Errorf(\"get labels %s: %w\", id, err) }\n}","preventionTips":["Retry transient read failures with backoff","Keep the local Dolt database in sync (bd dolt pull) before reading","Run migrations so labels tables exist","Include the ID in your own error context for diagnosis"],"tags":["labels","storage","database","read-failed"],"backgroundTag":"label-list-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}