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

  1. Validate with json.Valid(patch) before the call; treat empty patches as `{}` (JSONMerge already handles nil).
  2. Read the wrapped decoder error for the byte offset of the syntax problem in the patch.
  3. 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

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


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/785e435fc520efdd. Report an issue: GitHub.