gravitational/teleport · error
error in data JSON
Error message
error in data JSON: %w
What it means
JSONMerge in the accessgraph API client validates its inputs by unmarshalling the `data` (base) document into a generic value before applying the patch. If `data` is not valid JSON (syntax error, empty input, trailing garbage), the underlying decode error is wrapped and returned. The merge never runs, so no partial output is produced.
Solutions
- Validate the `data` payload with json.Valid(data) (or a test unmarshal) before calling JSONMerge; substitute `{}` when empty.
- Inspect the wrapped decode error (offset/syntax message) to find the exact corrupt position in the input.
- Trace upstream producers of `data` and fix the serialization/write path that emitted invalid JSON.
Example fix
// before
merged, err := jsonmerge.JSONMerge(data, patch)
// after
if len(bytes.TrimSpace(data)) == 0 { data = []byte("{}") }
if !json.Valid(data) { return nil, fmt.Errorf("invalid base data JSON") }
merged, err := jsonmerge.JSONMerge(data, patch) Defensive patterns
Strategy: validation
Validate before calling
if len(bytes.TrimSpace(data)) == 0 { data = []byte("{}") }
if !json.Valid(data) {
return nil, fmt.Errorf("refusing merge: data 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 data JSON") {
// base document corrupt: log hex/offset, fall back to raw data without merge
}
} Prevention
- Sanitize empty payloads to `{}` before merging.
- Log the first ~100 bytes of `data` on failure to spot YAML/log contamination.
- Fix producers to write JSON atomically (temp file + rename) to avoid truncated reads.
When it happens
Trigger: Calling JSONMerge (or any MergeActionTeleportProperties/MergeActionAWSProperties/MergeActionAzureProperties/MergeActionGitlabProperties/MergeActionOktaProperties which call it) with a `data` byte slice that is empty, malformed, truncated, or non-JSON content (e.g. YAML or a log line).
Common situations: Access Graph service responses or stored resources that failed to serialize earlier; reading a partially-written file; passing empty/nil-adjacent byte slices when a resource has no recorded properties.
Related errors
- error in patch JSON
- error writing merged JSON
- basic constraints not valid (BasicConstraintsValid=false)
- certificate or public key required
- certificate required
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/415c29f6b9dd7c0c.
Report an issue: GitHub.
Appendix: source
Thrown at lib/accessgraph/apiclient/jsonmerge/jsonmerge.go:40
"bytes"
"encoding/json"
"fmt"
"strconv"
)
// 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)View on GitHub (pinned to 1283425b60)