JuliusBrussee/caveman · error
json splice: invalid array range
Error message
json splice: invalid array range
What it means
AppendArrayElements splices elements before an array's closing bracket and validates that the span is in-bounds, non-empty, and actually brackets an array (starts '[' and ends ']'). Anything else aborts to keep the document byte-exact.
Solutions
- Verify body[span.Start]=='[' && body[span.End-1]==']' at the call site before appending
- Re-locate the array span on the current body bytes
- Branch on payload schema: use AppendObjectFields for object targets, AppendArrayElements only for real arrays
- Cache no spans across transforms; recompute after every mutation
Example fix
// before: object span passed to array append
out, err := jsonsplice.AppendArrayElements(body, objSpan, elem)
// after: locate the actual array
arrSpan, ok := findArraySpan(body, "system")
if !ok { return nil, fmt.Errorf("system is not an array") }
out, err := jsonsplice.AppendArrayElements(body, arrSpan, elem) Defensive patterns
Strategy: validation
Validate before calling
func isArraySpan(body []byte, s jsonsplice.Span) bool {
return s.Start >= 0 && s.End <= len(body) && s.Start < s.End && body[s.Start] == '[' && body[s.End-1] == ']'
} Try / catch
if !isArraySpan(body, span) { return nil, fmt.Errorf("target span is not a JSON array") }
out, err := jsonsplice.AppendArrayElements(body, span, elems...) Prevention
- Branch between AppendObjectFields and AppendArrayElements based on the actual decoded type
- Relocate the span on the current body before appending
- Assert locator endpoints on '[' and ']' in tests
When it happens
Trigger: injectConverseCachePointRaw given a span on a non-array (e.g. the 'system' object or a string field); stale span after re-serialization; bounds violation from End > len(body).
Common situations: Targeting a field that is an object in one provider schema and an array in another; span computed on a template body differing from the live one; locator off-by-one grabbing the last element instead of ']'.
Related errors
- json splice: invalid object range
- json splice: invalid range
- json splice: replacements for candidates
- json splice: invalid element insertion
- json splice: invalid field insertion
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/d075253050365ca5.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/providers/jsonsplice/jsonsplice.go:201
}
addition.Write(name)
addition.WriteByte(':')
addition.Write(field.Value)
}
out := make([]byte, 0, len(body)+addition.Len())
out = append(out, body[:insertAt]...)
out = append(out, addition.Bytes()...)
out = append(out, body[insertAt:]...)
return out, nil
}
// AppendArrayElements inserts elements immediately before an array's closing
// bracket. Existing bytes, whitespace, and element order remain untouched.
func AppendArrayElements(body []byte, array Span, elements ...[]byte) ([]byte, error) {
if array.Start < 0 || array.End > len(body) || array.Start >= array.End ||
body[array.Start] != '[' || body[array.End-1] != ']' {
return nil, fmt.Errorf("json splice: invalid array range")
}
if len(elements) == 0 {
return body, nil
}
insertAt := array.End - 1
for insertAt > array.Start+1 && bytes.ContainsRune([]byte(" \n\r\t"), rune(body[insertAt-1])) {
insertAt--
}
hasElements := insertAt > array.Start+1
var addition bytes.Buffer
if hasElements {
addition.WriteByte(',')
}
for i, element := range elements {
if !json.Valid(element) {
return nil, fmt.Errorf("json splice: invalid element insertion")View on GitHub (pinned to 3ee70a1026)