gastownhall/beads · error · storage.ErrValidation
%w: %w
Error message
%w: %w
What it means
This error wraps storage.ErrValidation together with the underlying ValidateMetadataKey error, thrown by ApplyMetadataPatch when a key in the metadata patch.Set map fails key validation. It signals that the update request carries a metadata key that violates the storage layer's key rules (e.g. empty, too long, or invalid characters), so the whole update is rejected before touching the database.
Source
Thrown at internal/storage/issueops/aggregate.go:200
if err != nil {
return err
}
return AuthorizeAssigneeTransferWithPools(before, request, pools)
}
// ApplyMetadataPatch returns the canonical metadata value and whether it changes.
func ApplyMetadataPatch(current json.RawMessage, patch publicops.MetadataPatch) (json.RawMessage, bool, error) {
if !patch.Replace.Set && !patch.Merge.Set && len(patch.Set) == 0 && len(patch.Unset) == 0 {
return current, false, nil
}
setKeys := make([]string, 0, len(patch.Set))
for key := range patch.Set {
setKeys = append(setKeys, key)
}
sort.Strings(setKeys)
for _, key := range setKeys {
if err := storage.ValidateMetadataKey(key); err != nil {
return nil, false, fmt.Errorf("%w: %w", storage.ErrValidation, err)
}
}
for _, key := range patch.Unset {
if err := storage.ValidateMetadataKey(key); err != nil {
return nil, false, fmt.Errorf("%w: %w", storage.ErrValidation, err)
}
}
var next json.RawMessage
if patch.Replace.Set {
next = append(json.RawMessage(nil), patch.Replace.Value...)
if len(next) == 0 {
next = json.RawMessage(`{}`)
}
if !json.Valid(next) {
return nil, false, fmt.Errorf("%w: metadata replacement is not valid JSON", storage.ErrValidation)
}
} else {
next = append(json.RawMessage(nil), current...)View on GitHub (pinned to 71377f2769)
Solutions
- Validate each metadata key with storage.ValidateMetadataKey before constructing the patch and drop or fix invalid keys.
- Trim and sanitize user-supplied keys (reject empty/whitespace keys) at the CLI/API boundary.
- Inspect the wrapped error message to identify the exact offending key and correct it.
Example fix
// before
patch.Set[rawKey] = json.RawMessage("1") // rawKey may be empty
// after
if err := storage.ValidateMetadataKey(rawKey); err != nil {
return fmt.Errorf("invalid metadata key %q: %w", rawKey, err)
}
patch.Set[rawKey] = json.RawMessage("1") Defensive patterns
Strategy: validation
Validate before calling
func validSetKeys(set map[string]json.RawMessage) error {
for k := range set {
if err := storage.ValidateMetadataKey(k); err != nil {
return fmt.Errorf("key %q: %w", k, err)
}
}
return nil
} Try / catch
if err := errors.Is(err, storage.ErrValidation) { /* surface invalid metadata key to caller, do not retry */ } Prevention
- Run storage.ValidateMetadataKey on every key before building a patch.
- Trim and reject empty/whitespace keys at the CLI boundary.
- Never build keys from unsanitized user input.
- Add a unit test covering key validation rules for patch construction.
When it happens
Trigger: Calling ApplyMetadataPatch (via ExecuteUpdate) with patch.Set containing at least one key for which storage.ValidateMetadataKey returns an error.
Common situations: Building metadata patches programmatically with empty-string keys; user-supplied JSON keys passed through CLI flags without sanitization; keys containing whitespace or control characters from copied config.
Related errors
- ExternalDoltConfig: must set Socket or (Host, Port)
- %w: cannot combine metadata replacement with incremental met
- %w: metadata replacement is not valid JSON
- %w: metadata merge must be a JSON object
- %w: metadata merge: %v
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f9f236d524d44aea.
Report an issue: GitHub.