gastownhall/beads · error
invalid status %q (valid: %s)
Error message
invalid status %q (valid: %s)
What it means
ApplyStatusFilter parses a status selector (single status or comma-separated set) onto an IssueFilter. If splitting the selector yields no parts — e.g. an empty or whitespace-only string after normalization — it is rejected as invalid, listing the valid statuses (built-ins plus custom status names).
Source
Thrown at internal/workapi/list.go:499
}
return false
}
// ValidStatusList renders the status names a filter accepts, for error text.
func ValidStatusList(customStatusNames []string) string {
validList := "open, in_progress, blocked, deferred, closed, pinned, hooked"
if len(customStatusNames) > 0 {
validList += ", " + strings.Join(customStatusNames, ", ")
}
return validList
}
// ApplyStatusFilter parses a status selector - one status, or a
// comma-separated OR set - onto the filter.
func ApplyStatusFilter(filter *types.IssueFilter, status string, customStatusNames []string) error {
parts := splitStatusSelector(status)
if len(parts) == 0 {
return fmt.Errorf("invalid status %q (valid: %s)", status, ValidStatusList(customStatusNames))
}
return applyStatusParts(filter, parts, customStatusNames)
}
func applyStatusParts(filter *types.IssueFilter, parts []string, customStatusNames []string) error {
if len(parts) == 1 {
s := types.Status(parts[0])
if !s.IsValidWithCustom(customStatusNames) {
return fmt.Errorf("invalid status %q (valid: %s)", parts[0], ValidStatusList(customStatusNames))
}
filter.Status = &s
return nil
}
for _, part := range parts {
s := types.Status(part)
if !s.IsValidWithCustom(customStatusNames) {
// "all" is a real selector on its own (every status), so failingView on GitHub (pinned to 71377f2769)
Solutions
- Pass a non-empty status or comma-separated list, e.g. "open" or "open,in-progress"
- Check that the variable feeding the status parameter is populated
- Use ValidStatusList(customStatusNames) to present valid choices before calling
- If you want every status, pass the literal selector "all" instead of an empty string
Example fix
// before
workapi.ApplyStatusFilter(&filter, status, customStatuses) // status == " "
// after
if strings.TrimSpace(status) != "" {
workapi.ApplyStatusFilter(&filter, status, customStatuses)
} Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(status) != "" {
if err := workapi.ApplyStatusFilter(&filter, status, customStatusNames); err != nil { return err }
} Try / catch
err := workapi.ApplyStatusFilter(&filter, status, customNames)
if err != nil {
return fmt.Errorf("bad --status %q; valid: %s", status, workapi.ValidStatusList(customNames))
} Prevention
- Trim/validate status input before passing it
- Never pass empty/whitespace-only status strings from scripts
- Use ValidStatusList to validate or present options first
- Prefer the "all" literal over an empty string for every-status queries
When it happens
Trigger: Calling ApplyStatusFilter with a status string that reduces to zero parts via splitStatusSelector (empty string, only commas/whitespace) even though a status was requested.
Common situations: Passing an empty --status flag value; shell quoting yielding only whitespace; programmatic callers building a status string from a variable that is empty.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- status "all" cannot be combined with other statuses
- invalid status %q in multi-status filter (valid: %s)
- got %d close reasons for %d issue IDs; provide exactly one s
- cannot specify both --reason-file and --reason/--resolution/
- --reason-file %q is empty; close reason is required
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ff58eabee9982af4.
Report an issue: GitHub.