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
A value supplied for a metadata set operation is not valid JSON. Each value in a typed set edit must be a valid JSON document (json.Valid check) before it is written into the metadata object.
Source
Thrown at internal/storage/issueops/update.go:945
if len(existing) > 0 {
trimmed := strings.TrimSpace(string(existing))
if trimmed != "" && trimmed != "null" {
if err := json.Unmarshal(existing, &data); err != nil {
return nil, fmt.Errorf("existing metadata is not a JSON object: %w", err)
}
}
}
keys := make([]string, 0, len(set))
for key := range set {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
if err := storage.ValidateMetadataKey(key); err != nil {
return nil, err
}
if !json.Valid(set[key]) {
return nil, fmt.Errorf("metadata value for key %q is not valid JSON", key)
}
data[key] = set[key]
}
for _, key := range unset {
if err := storage.ValidateMetadataKey(key); err != nil {
return nil, err
}
delete(data, key)
}
result, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal metadata: %w", err)
}
return json.RawMessage(result), nil
}
// resolveNotesAppendOp folds OpAppendNotes into a concrete "notes" value on
// resolved, appending to oldIssue.Notes (read in the same mutation transaction).View on GitHub (pinned to 71377f2769)
Solutions
- Run json.Valid (or json.Marshal the value) before placing it in the set map
- Build values with json.Marshal(value) instead of hand-crafted strings
- For string values, ensure they are quoted JSON strings: json.RawMessage(`"text"`), not json.RawMessage(`text`)
Example fix
// before
set["note"] = json.RawMessage(`hello world`) // invalid JSON
// after
b, _ := json.Marshal("hello world")
set["note"] = b // "hello world" Defensive patterns
Strategy: validation
Validate before calling
for key, val := range set {
if !json.Valid(val) {
return fmt.Errorf("key %q: value is not valid JSON", key)
}
} Type guard
func validJSONValue(raw json.RawMessage) bool { return json.Valid(raw) } Try / catch
if err := issueops.ResolveMergeOps(issue, updates, resolved); err != nil {
if strings.Contains(err.Error(), "is not valid JSON") {
return fmt.Errorf("fix the metadata value before retrying: %w", err)
}
} Prevention
- Build values with json.Marshal instead of string literals
- Remember strings need quotes in JSON: "\"text\"" not "text"
- Run json.Valid on all externally supplied values before submitting
When it happens
Trigger: Calling an update with OpSetMetadata whose map contains a json.RawMessage (or equivalent) that is malformed JSON, e.g. RawMessage built from a non-serialized Go string.
Common situations: Constructing json.RawMessage from raw user text without json.Marshal, hand-writing JSON in CLI args with quoting errors, or templating that interpolates Go values as strings instead of JSON.
Related errors
- ExternalDoltConfig: must set Socket or (Host, Port)
- metadata.repo: %w
- metadata.repo must not be null
- loading config for gate resolution: %w
- invalid metadata: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ca3f22db984ea2fd.
Report an issue: GitHub.