gastownhall/beads · error · issueops.ErrValidation
%w: apply batch item %d has unknown kind %q
Error message
%w: apply batch item %d has unknown kind %q
What it means
The item's Kind field must be one of the known kinds (ItemCreate, ItemUpdate, ItemClose, ItemDepAdd). An unrecognized Kind hits the switch's default case and fails with the index and the offending kind string, wrapped with issueops.ErrValidation.
Source
Thrown at internal/storage/batch_apply.go:137
payloads++
}
}
if payloads != 1 {
return nil, fmt.Errorf("%w: apply batch item %d must carry exactly one payload, got %d",
issueops.ErrValidation, i, payloads)
}
var matches bool
switch item.Kind {
case issueops.ItemCreate:
matches = item.Create != nil
case issueops.ItemUpdate:
matches = item.Update != nil
case issueops.ItemClose:
matches = item.Close != nil
case issueops.ItemDepAdd:
matches = item.DepAdd != nil
default:
return nil, fmt.Errorf("%w: apply batch item %d has unknown kind %q", issueops.ErrValidation, i, item.Kind)
}
if !matches {
return nil, fmt.Errorf("%w: apply batch item %d is kind %q but carries another kind's payload",
issueops.ErrValidation, i, item.Kind)
}
if item.Create == nil {
continue
}
if item.Create.Issue == nil {
return nil, fmt.Errorf("%w: apply batch item %d requires an issue", issueops.ErrValidation, i)
}
if len(item.Create.Issue.Comments) > 0 || len(item.Create.Issue.Dependencies) > 0 {
return nil, fmt.Errorf("%w: apply batch item %d must not carry comments or dependencies on the issue; edges are their own items",
issueops.ErrValidation, i)
}
if item.Create.Key == "" {
continue
}View on GitHub (pinned to 71377f2769)
Solutions
- Use the exported constants (issueops.ItemCreate, etc.) instead of raw strings.
- Fix the kind string to exactly match one of the supported constants.
- Check for API version drift if the kind was valid in an older version.
Example fix
// before
item := issueops.ApplyBatchItem{Kind: "create", Create: cr}
// after
item := issueops.ApplyBatchItem{Kind: issueops.ItemCreate, Create: cr} Defensive patterns
Strategy: validation
Validate before calling
switch it.Kind {
case issueops.ItemCreate, issueops.ItemUpdate, issueops.ItemClose, issueops.ItemDepAdd:
// ok
default:
return fmt.Errorf("unknown kind %q", it.Kind)
} Type guard
func knownKind(k issueops.ItemKind) bool {
switch k {
case issueops.ItemCreate, issueops.ItemUpdate, issueops.ItemClose, issueops.ItemDepAdd:
return true
}
return false
} Try / catch
_, err := storage.PlanApplyBatch(req)
if errors.Is(err, issueops.ErrValidation) && strings.Contains(err.Error(), "unknown kind") {
return fmt.Errorf("unsupported batch item kind: %w", err)
} Prevention
- Always use exported Kind constants, never string literals.
- Check the library's kind constants after upgrades for renames.
- Reject unknown kinds at deserialization time before planning.
When it happens
Trigger: Setting Kind to a typo'd or made-up string (e.g. "creat", "delete"), or a zero-value Kind when the kind enum uses non-zero string constants.
Common situations: Hand-written JSON batches with an invalid kind; code written against an older/newer API where kinds changed; structs built without initializing Kind.
Related errors
- ExternalDoltConfig: TLSCert set without TLSKey
- formula %q: %w
- %w: apply batch requires an actor
- %w: apply batch requires at least one item
- %w: apply batch accepts at most %d items, got %d
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/32eeecc551e9c03c.
Report an issue: GitHub.