{"record":{"id":"8067b88f28822176","repo":"gastownhall/beads","slug":"countissuesbygroup-w","errorCode":null,"errorMessage":"CountIssuesByGroup: %w","messagePattern":"CountIssuesByGroup: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1841,"sourceCode":"\tout, err := u.issueRepo.GetStatistics(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GetStatistics: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) CountIssues(ctx context.Context, query string, filter types.IssueFilter) (int64, error) {\n\tout, err := u.issueRepo.CountIssues(ctx, query, filter)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"CountIssues: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) CountIssuesByGroup(ctx context.Context, filter types.IssueFilter, groupBy string) (map[string]int, error) {\n\tout, err := u.issueRepo.CountIssuesByGroup(ctx, filter, groupBy)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"CountIssuesByGroup: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) History(ctx context.Context, id string) ([]*storage.HistoryEntry, error) {\n\tout, err := u.issueRepo.History(ctx, id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"History: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) IterEvents(ctx context.Context, id string, limit int) (storage.Iter[types.Event], error) {\n\tout, err := u.issueRepo.IterEvents(ctx, id, limit)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"IterEvents: %w\", err)\n\t}\n\treturn out, nil","sourceCodeStart":1823,"sourceCodeEnd":1859,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1823-L1859","documentation":"Pass-through wrapper from CountIssuesByGroup in the issue use-case: wraps errors from issueRepo.CountIssuesByGroup(ctx, filter, groupBy), which counts issues bucketed by a grouping column (e.g. status, priority, assignee). Failures in the group-by storage query surface as 'CountIssuesByGroup: <root cause>'.","triggerScenarios":"Calling CountIssuesByGroup with an unsupported groupBy field name (storage rejects unknown columns) or when the aggregate group query fails due to filter errors or storage outage.","commonSituations":"Reporting tools passing typo'd groupBy values (e.g. 'priorty' instead of 'priority'); filters referencing nonexistent labels; database unreachable during dashboard refreshes.","solutions":["Inspect the wrapped error after 'CountIssuesByGroup:' for the root cause","Verify groupBy is a supported column name (status, priority, type, assignee, etc.)","Validate IssueFilter values before calling","Retry on transient storage errors"],"exampleFix":"// before\ngroups, err := uc.CountIssuesByGroup(ctx, filter, \"priorty\")\n// after\ngroups, err := uc.CountIssuesByGroup(ctx, filter, \"priority\")","handlingStrategy":"validation","validationCode":"var validGroups = map[string]bool{\"status\":true,\"priority\":true,\"type\":true,\"assignee\":true}\nif !validGroups[groupBy] {\n    return fmt.Errorf(\"unsupported groupBy: %s\", groupBy)\n}","typeGuard":"func validGroupBy(g string) bool {\n    switch g {\n    case \"status\", \"priority\", \"type\", \"assignee\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"groups, err := uc.CountIssuesByGroup(ctx, filter, groupBy)\nif err != nil {\n    log.Warnf(\"group counts unavailable for %s: %v\", groupBy, err)\n    return map[string]int{}\n}","preventionTips":["Whitelist supported groupBy values before calling","Validate IssueFilter values before group queries","Retry transient storage errors","Use constants (not hand-typed strings) for groupBy names"],"tags":["go","storage","error-wrapping","group-by"],"backgroundTag":"repository-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}