gastownhall/beads · error
metadata value for key %q is not valid JSON
Error message
metadata value for key %q is not valid JSON
What it means
Each key in the Set map must have a value that is valid JSON (json.Valid). This per-key check rejects individual bad values and names the offending key, after ValidateMetadataKey approves the key itself.
Source
Thrown at internal/storage/uow/issue_operations.go:568
return fmt.Errorf("metadata replacement is not valid JSON")
}
if metadata.Merge.Set {
var object map[string]json.RawMessage
if len(metadata.Merge.Value) == 0 || json.Unmarshal(metadata.Merge.Value, &object) != nil || object == nil {
return fmt.Errorf("metadata merge must be a JSON object")
}
}
keys := make([]string, 0, len(metadata.Set))
for key := range metadata.Set {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
if err := storage.ValidateMetadataKey(key); err != nil {
return err
}
if !json.Valid(metadata.Set[key]) {
return fmt.Errorf("metadata value for key %q is not valid JSON", key)
}
}
for _, key := range metadata.Unset {
if err := storage.ValidateMetadataKey(key); err != nil {
return err
}
}
return nil
}
func validateReopenRequest(request publicops.ReopenRequest) error {
if request.Actor == "" || request.IssueID == "" {
return validationError(fmt.Errorf("reopen: actor and issue ID must not be empty"))
}
return nil
}
func semanticIssueEqual(left, right *types.Issue) bool {View on GitHub (pinned to 71377f2769)
Solutions
- Wrap non-JSON scalar values in quotes or marshal them with json.Marshal
- Validate each value with json.Valid before building the patch
- Use a helper that converts Go values via json.Marshal rather than raw bytes
- Quote string values in shell: --set priority='"high"'
Example fix
// before
patch.Metadata.Set["priority"] = []byte(`high`)
// after
v, _ := json.Marshal("high")
patch.Metadata.Set["priority"] = v Defensive patterns
Strategy: validation
Validate before calling
func validSetValues(set map[string]json.RawMessage) error {
for k, v := range set {
if err := storage.ValidateMetadataKey(k); err != nil { return err }
if !json.Valid(v) { return fmt.Errorf("value for %q is not valid JSON", k) }
}
return nil
} Try / catch
if err := uc.Update(ctx, req); err != nil {
if errors.Is(err, publicops.ErrValidation) && strings.Contains(err.Error(), "valid JSON") {
// extract the offending key from the message, fix its value, retry
}
return err
} Prevention
- Marshal scalar values with json.Marshal so strings get quoted
- For CLI --set input, require properly quoted JSON values (e.g. '"high"')
- Validate all Set values with json.Valid at patch-build time
- Reject empty values early — empty bytes are never valid JSON
When it happens
Trigger: Calling Update with Patch.Metadata.Set containing an entry whose json.RawMessage / []byte value is not parseable JSON — e.g. []byte(`high`) instead of []byte(`"high"`), or an empty value.
Common situations: Users passing raw strings via CLI --set flags without quoting, values built with fmt.Sprintf instead of json.Marshal, or empty strings from unset environment variables.
Related errors
- metadata replacement is not valid JSON
- ExternalDoltConfig: must set Socket or (Host, Port)
- %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/9fb46a2ccd9072d9.
Report an issue: GitHub.