gastownhall/beads · error
invalid metadata key filter: %w
Error message
invalid metadata key filter: %w
What it means
ValidateMetadataFilters rejects the --has-key (hasKey) argument when storage.ValidateMetadataKey deems it malformed. The library validates metadata keys up front so a bad key fails fast instead of producing a filter that can never match. The wrapped inner error from ValidateMetadataKey names the specific rule violated.
Source
Thrown at internal/workapi/metadata.go:28
// ValidateMetadataFilters refuses a metadata key the query layer cannot spell.
//
// Both builders call it, so the leaf contract's "keys are validated inside" is
// true of every Reader implementation rather than of the CLI only. Before it
// existed the sole check lived in the SQL builder, whose error surfaced wrapped
// in the storage method's name — a shape nothing above storage can classify —
// so a typo'd key reached `bd list` as a usage error and the HTTP surface as a
// 500, on a parameter the frozen document promises a 400 for.
//
// The CLI still validates the same input at flag-parse time and still reports
// it in its own words: this is the floor under every caller, not a replacement
// for a front door's usage error.
//
// Keys are checked in sorted order so a request with two bad keys always names
// the same one.
func ValidateMetadataFilters(fields map[string]string, hasKey string) error {
if hasKey != "" {
if err := storage.ValidateMetadataKey(hasKey); err != nil {
return fmt.Errorf("invalid metadata key filter: %w", err)
}
}
keys := make([]string, 0, len(fields))
for k := range fields {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
if err := storage.ValidateMetadataKey(k); err != nil {
return fmt.Errorf("invalid metadata field key: %w", err)
}
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped ValidateMetadataKey error to see which rule the key breaks
- Normalize the key: trim whitespace, remove disallowed characters, match the allowed pattern/length
- If the intent is to filter on a field, verify the exact key with `bd show` on a known issue carrying that metadata
Example fix
// before bd list --has-key "review status" // after bd list --has-key "review-status"
Defensive patterns
Strategy: validation
Validate before calling
if hasKey != "" {
if err := storage.ValidateMetadataKey(hasKey); err != nil {
return fmt.Errorf("--has-key: %w", err)
}
} Try / catch
err := ValidateMetadataFilters(fields, hasKey)
if err != nil && strings.HasPrefix(err.Error(), "invalid metadata key filter") {
return fmt.Errorf("check --has-key value: %w", err)
} Prevention
- Trim and sanitize key input before passing --has-key
- Reuse storage.ValidateMetadataKey in your own flag parsing for early feedback
- Keep metadata keys to the documented charset and length
When it happens
Trigger: Calling BuildListFilter or BuildReadyFilter with fields/hasKey where hasKey fails ValidateMetadataKey — e.g. an empty-or-whitespace key, a key with illegal characters, or one exceeding the length cap.
Common situations: Scripting `bd list --has-key` with a value containing spaces or dots; passing a JSON-style dotted path when only flat alphanumeric keys are allowed; copy-pasting a label that includes trailing whitespace.
Related errors
- invalid metadata field key: %w
- invalid status %q in multi-status filter (valid: %s)
- ExternalDoltConfig: must set Socket or (Host, Port)
- got %d close reasons for %d issue IDs; provide exactly one s
- cannot specify both --reason-file and --reason/--resolution/
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b6c31f51fa4d6480.
Report an issue: GitHub.