{"record":{"id":"d4964674e41e99a3","repo":"gastownhall/beads","slug":"invalid-group-s-valid-values-status-priority","errorCode":null,"errorMessage":"invalid group '%s'. Valid values: status, priority, type, assignee, label%.0w","messagePattern":"invalid group '(.+?)'\\. Valid values: status, priority, type, assignee, label%\\.0w","errorType":"validation","errorClass":"issueops.ErrValidation","httpStatus":null,"severity":"error","filePath":"internal/workapi/count.go","lineNumber":29,"sourceCode":"\n// countGroupColumns is the closed set issueops.CountByGroupRequest.GroupBy\n// promises, mapped to what the storage seam calls each dimension. It exists so\n// an unknown value is refused HERE, as ErrValidation, rather than reaching\n// storage and coming back as an unclassifiable \"unsupported groupBy\" string.\nvar countGroupColumns = map[issueops.CountGroup]string{\n\tissueops.CountGroupStatus:   \"status\",\n\tissueops.CountGroupPriority: \"priority\",\n\tissueops.CountGroupType:     \"type\",\n\tissueops.CountGroupAssignee: \"assignee\",\n\tissueops.CountGroupLabel:    \"label\",\n}\n\n// ValidateCountGroup resolves a grouping dimension to the name the storage\n// seam takes, refusing anything outside the published set with ErrValidation.\nfunc ValidateCountGroup(group issueops.CountGroup) (string, error) {\n\tcolumn, ok := countGroupColumns[group]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid group '%s'. Valid values: status, priority, type, assignee, label%.0w\",\n\t\t\tgroup, issueops.ErrValidation)\n\t}\n\treturn column, nil\n}\n\n// BuildCountFilter turns a count request into the storage-level filter: the\n// single definition of what `bd count` means, which every implementation of\n// issueops.Counter builds through.\n//\n// It is a SEPARATE builder rather than a call into BuildListFilter with the\n// paging fields blanked out, because the two commands disagree about the\n// default answer: a listing hides closed, pinned, template and gate rows, and a\n// count hides none of them. The one place they must agree is --include-infra,\n// pinned by a golden-style test comparing this builder's output against\n// BuildListFilter's for the same request (count_test.go, GH#4387).\n//\n// cfg supplies the workspace's infra vocabulary and is only read under\n// IncludeInfra; a zero ListConfig falls back to the default infra set.","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/workapi/count.go#L11-L47","documentation":"ValidateCountGroup refuses a grouping dimension outside the published set {status, priority, type, assignee, label}, wrapping the message with issueops.ErrValidation (via %.0w). Count queries group by exactly one recognized dimension; unknown names have no storage column mapping in countGroupColumns.","triggerScenarios":"Calling a count operation with issueops.CountGroup set to a value not present in countGroupColumns — e.g. a typo'd or newly invented group name passed to ValidateCountGroup.","commonSituations":"Misspelling a group name (\"statues\", \"assigne\"); using a plausible-but-unsupported dimension like \"state\" or \"milestone\"; older code constructing CountGroup values after the dimension set changed.","solutions":["Use one of the valid groups: status, priority, type, assignee, label","Check the CountGroup constant definitions rather than casting raw strings","If a new dimension is genuinely needed, file a feature request to add it to countGroupColumns"],"exampleFix":"// before\ncol, err := ValidateCountGroup(issueops.CountGroup(\"state\"))\n// after\ncol, err := ValidateCountGroup(issueops.CountGroup(\"status\"))","handlingStrategy":"validation","validationCode":"var validGroups = map[issueops.CountGroup]bool{\n    \"status\": true, \"priority\": true, \"type\": true, \"assignee\": true, \"label\": true,\n}\nif !validGroups[g] { return fmt.Errorf(\"unsupported count group %q\", g) }","typeGuard":null,"tryCatchPattern":"col, err := workapi.ValidateCountGroup(g)\nif errors.Is(err, issueops.ErrValidation) {\n    return fmt.Errorf(\"%w (valid: status, priority, type, assignee, label)\", err)\n}","preventionTips":["Use named CountGroup constants instead of raw strings","Keep UI/menu options synced to the five valid dimensions","Add a unit test enumerating allowed groups"],"tags":["validation","count","grouping","issueops"],"backgroundTag":"invalid-group-dimension","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}