gastownhall/beads · error · issueops.ErrValidation
invalid group '%s'. Valid values: status, priority, type, as
Error message
invalid group '%s'. Valid values: status, priority, type, assignee, label%.0w
What it means
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.
Source
Thrown at internal/workapi/count.go:29
// countGroupColumns is the closed set issueops.CountByGroupRequest.GroupBy
// promises, mapped to what the storage seam calls each dimension. It exists so
// an unknown value is refused HERE, as ErrValidation, rather than reaching
// storage and coming back as an unclassifiable "unsupported groupBy" string.
var countGroupColumns = map[issueops.CountGroup]string{
issueops.CountGroupStatus: "status",
issueops.CountGroupPriority: "priority",
issueops.CountGroupType: "type",
issueops.CountGroupAssignee: "assignee",
issueops.CountGroupLabel: "label",
}
// ValidateCountGroup resolves a grouping dimension to the name the storage
// seam takes, refusing anything outside the published set with ErrValidation.
func ValidateCountGroup(group issueops.CountGroup) (string, error) {
column, ok := countGroupColumns[group]
if !ok {
return "", fmt.Errorf("invalid group '%s'. Valid values: status, priority, type, assignee, label%.0w",
group, issueops.ErrValidation)
}
return column, nil
}
// BuildCountFilter turns a count request into the storage-level filter: the
// single definition of what `bd count` means, which every implementation of
// issueops.Counter builds through.
//
// It is a SEPARATE builder rather than a call into BuildListFilter with the
// paging fields blanked out, because the two commands disagree about the
// default answer: a listing hides closed, pinned, template and gate rows, and a
// count hides none of them. The one place they must agree is --include-infra,
// pinned by a golden-style test comparing this builder's output against
// BuildListFilter's for the same request (count_test.go, GH#4387).
//
// cfg supplies the workspace's infra vocabulary and is only read under
// IncludeInfra; a zero ListConfig falls back to the default infra set.View on GitHub (pinned to 71377f2769)
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
Example fix
// before
col, err := ValidateCountGroup(issueops.CountGroup("state"))
// after
col, err := ValidateCountGroup(issueops.CountGroup("status")) Defensive patterns
Strategy: validation
Validate before calling
var validGroups = map[issueops.CountGroup]bool{
"status": true, "priority": true, "type": true, "assignee": true, "label": true,
}
if !validGroups[g] { return fmt.Errorf("unsupported count group %q", g) } Try / catch
col, err := workapi.ValidateCountGroup(g)
if errors.Is(err, issueops.ErrValidation) {
return fmt.Errorf("%w (valid: status, priority, type, assignee, label)", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- count by id: sourceID must not be empty
- %w: bootstrap requires a non-empty issue prefix
- %w: bootstrap requires a project id; this role does not mint
- %w: delete requires at least one issue id
- %w: delete id at position %d is blank
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d4964674e41e99a3.
Report an issue: GitHub.