{"record":{"id":"5ae7a784a3facd5d","repo":"gastownhall/beads","slug":"countissues-w","errorCode":null,"errorMessage":"CountIssues: %w","messagePattern":"CountIssues: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1833,"sourceCode":"\tout, err := u.issueRepo.GetBlockedIssues(ctx, filter)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GetBlockedIssues: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) GetStatistics(ctx context.Context) (*types.Statistics, error) {\n\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","sourceCodeStart":1815,"sourceCodeEnd":1851,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1815-L1851","documentation":"Pass-through wrapper from CountIssues in the issue use-case: wraps errors from issueRepo.CountIssues(ctx, query, filter), which counts issues matching a free-text query plus structured filter. The count query failing in storage surfaces as 'CountIssues: <root cause>'.","triggerScenarios":"Calling CountIssues(ctx, query, filter) when the repository count query errors — malformed free-text query syntax, invalid filter, or storage failure while executing the count SQL.","commonSituations":"Scripts passing user-supplied search strings with bad query syntax; filters with invalid status/priority values; database outage during batch reporting jobs.","solutions":["Inspect the wrapped error after 'CountIssues:' for the root cause","Validate the query string syntax and IssueFilter values before calling","Sanitize/escape user-supplied query input","Retry on transient storage errors"],"exampleFix":"// before\ncount, err := uc.CountIssues(ctx, userQuery, filter)\n// after\ncount, err := uc.CountIssues(ctx, userQuery, filter)\nif err != nil {\n    return fmt.Errorf(\"counting issues for query %q: %w\", userQuery, err)\n}","handlingStrategy":"validation","validationCode":"if query == \"\" && filter == (types.IssueFilter{}) {\n    return fmt.Errorf(\"empty query and filter\")\n}\n// validate query syntax against supported operators before calling","typeGuard":null,"tryCatchPattern":"count, err := uc.CountIssues(ctx, query, filter)\nif err != nil {\n    return fmt.Errorf(\"count failed for query %q: %w\", query, err)\n}","preventionTips":["Validate/sanitize free-text query syntax before passing to CountIssues","Validate IssueFilter enum values (status, priority, type)","Escape user-supplied input in query construction","Retry transient storage errors in batch jobs"],"tags":["go","storage","error-wrapping","count-query"],"backgroundTag":"repository-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}