JuliusBrussee/caveman · error

json splice: invalid element insertion

Error message

json splice: invalid element insertion

What it means

AppendArrayElements requires every element to be valid JSON because bytes are inserted verbatim before the closing bracket. Invalid element bytes abort the splice to prevent producing a corrupt document.

Solutions

  1. Build each element with json.Marshal and check its error before appending to the elements slice
  2. Add json.Valid checks in tests for all element payloads
  3. Never pass nil/empty bytes; skip the append entirely when there is nothing to insert

Example fix

// before: concatenated element
elem := []byte(fmt.Sprintf(`{"type": %s}`, kind))
out, err := jsonsplice.AppendArrayElements(body, span, elem)
// after: marshal the struct
raw, err := json.Marshal(cachePoint{Type: kind})
if err != nil { return nil, err }
out, err := jsonsplice.AppendArrayElements(body, span, raw)
Defensive patterns

Strategy: validation

Validate before calling

for i, e := range elements {
    if len(e) == 0 || !json.Valid(e) { return fmt.Errorf("element %d is not valid JSON: %q", i, e) }
}

Try / catch

if err := validateElements(elements); err != nil { return nil, err }
out, err := jsonsplice.AppendArrayElements(body, span, elements...)

Prevention

When it happens

Trigger: Element built via string concatenation or fmt.Sprintf with unquoted strings; empty/nil element bytes; partially failed marshal passed through.

Common situations: Cache-point objects serialized with a non-JSON encoder; interpolating raw strings into []byte; a marshal error earlier ignored, leaving truncated JSON in the element.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/7e21425564275e8f. Report an issue: GitHub.

Appendix: source

Thrown at proxy/providers/jsonsplice/jsonsplice.go:219

		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")
		}
		if i > 0 {
			addition.WriteByte(',')
		}
		addition.Write(element)
	}

	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
}

func value(body []byte, start int) (int, bool) {
	i := space(body, start)
	if i >= len(body) {
		return 0, false

View on GitHub (pinned to 3ee70a1026)