gastownhall/beads · error

invalid issue type %q (valid: %s)

Error message

invalid issue type %q (valid: %s)

What it means

BuildListFilter validates the requested --type value against the built-in issue types (bug, feature, task, epic, chore, decision) plus any custom types loaded into ListConfig. An unrecognized type string is rejected with the full list of valid values.

Source

Thrown at internal/workapi/list.go:262

		filter.ExcludeStatus = excludeStatuses
	}

	if in.Priority != nil {
		p := *in.Priority
		filter.Priority = &p
	}
	if in.Assignee != "" {
		a := in.Assignee
		filter.Assignee = &a
	}
	if in.IssueType != "" {
		t := types.IssueType(in.IssueType)
		if !t.IsValidWithCustom(cfg.CustomTypes) {
			validTypes := "bug, feature, task, epic, chore, decision"
			if len(cfg.CustomTypes) > 0 {
				validTypes += ", " + strings.Join(cfg.CustomTypes, ", ")
			}
			return filter, fmt.Errorf("invalid issue type %q (valid: %s)", in.IssueType, validTypes)
		}
		filter.IssueType = &t
	}

	if len(in.Labels) > 0 {
		filter.Labels = in.Labels
	}
	if len(in.LabelsAny) > 0 {
		filter.LabelsAny = in.LabelsAny
	}
	if len(in.ExcludeLabels) > 0 {
		filter.ExcludeLabels = in.ExcludeLabels
	}
	if in.LabelPattern != "" {
		filter.LabelPattern = in.LabelPattern
	}
	if in.LabelRegex != "" {
		filter.LabelRegex = in.LabelRegex

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use one of the valid built-in types: bug, feature, task, epic, chore, decision
  2. If you meant a custom type, verify it is registered in config.yaml or via `bd type` and that the ListConfig was loaded with those custom types (LoadListConfig)
  3. Fix the spelling/casing of the type string
  4. Re-load ListConfig from the workspace so cfg.CustomTypes includes the new type

Example fix

// before
req.IssueType = "feat"
// after
req.IssueType = "feature" // or register 'feat' as a custom type and reload ListConfig
Defensive patterns

Strategy: validation

Validate before calling

func validType(t string, custom []string) bool {
    for _, v := range append([]string{"bug","feature","task","epic","chore","decision"}, custom...) {
        if v == t { return true }
    }
    return false
}
if in.IssueType != "" && !validType(in.IssueType, cfg.CustomTypes) { return err }

Try / catch

filter, err := workapi.BuildListFilter(req, cfg)
if err != nil && strings.HasPrefix(err.Error(), "invalid issue type") {
    return fmt.Errorf("choose a type from: %s", err)
}

Prevention

When it happens

Trigger: Passing issueops.ListRequest with IssueType set to a value not in the built-in set nor in cfg.CustomTypes — e.g. a typo ('feat'), a custom type defined after the config was loaded, or calling BuildListFilter with an empty ListConfig that omits configured custom types.

Common situations: Typo in CLI --type flag; custom type added to YAML but not present in the store so CustomTypes falls back to YAML (or vice versa); using a custom type before bdinit registered it; stale config cache missing a newly added custom type.

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/0114f46ec765053b. Report an issue: GitHub.