gravitational/teleport · error
error in patch JSON: %w
Error message
error in patch JSON: %w
What it means
JSONMerge validates the `patch` document the same way as the base: it unmarshals the patch into a generic value before merging. If the patch bytes are not valid JSON, the decode error is wrapped and returned and the merge is aborted. Note a nil patch is tolerated (treated as `{}`), so this error only fires on non-empty invalid bytes.
Source
Thrown at lib/accessgraph/apiclient/jsonmerge/jsonmerge.go:45
// JSONMerge merges patch into data using the object-merge behavior expected by
// the generated union helpers.
func JSONMerge(data, patch json.RawMessage) (json.RawMessage, error) {
if data == nil {
data = []byte(`{}`)
}
if patch == nil {
patch = []byte(`{}`)
}
var dataValue any
if err := unmarshalJSON(data, &dataValue); err != nil {
return nil, fmt.Errorf("error in data JSON: %w", err)
}
var patchValue any
if err := unmarshalJSON(patch, &patchValue); err != nil {
return nil, fmt.Errorf("error in patch JSON: %w", err)
}
merged, err := json.Marshal(mergeJSON(dataValue, patchValue))
if err != nil {
return nil, fmt.Errorf("error writing merged JSON: %w", err)
}
return merged, nil
}
func unmarshalJSON(data []byte, value any) error {
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.UseNumber()
return decoder.Decode(value)
}
func mergeJSON(data, patch any) any {
patchObject, ok := patch.(map[string]any)
if !ok {View on GitHub (pinned to 1283425b60)
Solutions
- Validate with json.Valid(patch) before the call; treat empty patches as `{}` (JSONMerge already handles nil).
- Read the wrapped decoder error for the byte offset of the syntax problem in the patch.
- Fix the exporter/producer that generated the malformed patch document.
Example fix
// before
merged, err := jsonmerge.JSONMerge(data, patch)
// after
if !json.Valid(patch) { return nil, fmt.Errorf("invalid patch JSON") }
merged, err := jsonmerge.JSONMerge(data, patch) Defensive patterns
Strategy: validation
Validate before calling
if len(patch) == 0 { patch = []byte("{}") } // nil is tolerated, empty bytes may not be
if !json.Valid(patch) {
return nil, fmt.Errorf("refusing merge: patch is not valid JSON")
}
merged, err := jsonmerge.JSONMerge(data, patch) Type guard
func isValidJSON(b []byte) bool { return json.Valid(b) } Try / catch
merged, err := jsonmerge.JSONMerge(data, patch)
if err != nil {
if strings.Contains(err.Error(), "error in patch JSON") {
// patch corrupt: skip the patch or re-fetch from the exporter
}
} Prevention
- Validate every patch document at the producer boundary (exporters, queue consumers).
- Treat empty/whitespace patches as `{}` instead of raw empty byte slices.
- Round-trip patches through json.Marshal after generation to guarantee well-formedness.
When it happens
Trigger: Calling JSONMerge or a MergeAction*Properties wrapper with a `patch` argument containing malformed JSON — truncated update payloads, concatenated JSON objects, or non-JSON bytes from an external system (AWS/Teleport/Azure/GitLab/Okta import pipelines).
Common situations: Access Graph sync jobs receiving corrupted update documents from discovered-resource exporters; manual edits to stored patch files; wire/queue messages truncated mid-payload.
Related errors
- error in data JSON: %w
- error writing merged JSON: %w
- invalid resize dimensions
- nil certificate override
- invalid public key
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/785e435fc520efdd.
Report an issue: GitHub.