{"record":{"id":"377dce447c33a296","repo":"JuliusBrussee/caveman","slug":"json-splice-invalid-field-insertion","errorCode":null,"errorMessage":"json splice: invalid field insertion","messagePattern":"json splice: invalid field insertion","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/jsonsplice/jsonsplice.go","lineNumber":175,"sourceCode":"\t\treturn nil, fmt.Errorf(\"json splice: invalid object range\")\n\t}\n\tif len(fields) == 0 {\n\t\treturn body, nil\n\t}\n\n\tinsertAt := object.End - 1\n\tfor insertAt > object.Start+1 && bytes.ContainsRune([]byte(\" \\n\\r\\t\"), rune(body[insertAt-1])) {\n\t\tinsertAt--\n\t}\n\thasFields := insertAt > object.Start+1\n\n\tvar addition bytes.Buffer\n\tif hasFields {\n\t\taddition.WriteByte(',')\n\t}\n\tfor i, field := range fields {\n\t\tif field.Name == \"\" || !json.Valid(field.Value) {\n\t\t\treturn nil, fmt.Errorf(\"json splice: invalid field insertion\")\n\t\t}\n\t\tif i > 0 {\n\t\t\taddition.WriteByte(',')\n\t\t}\n\t\tname, err := json.Marshal(field.Name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\taddition.Write(name)\n\t\taddition.WriteByte(':')\n\t\taddition.Write(field.Value)\n\t}\n\n\tout := make([]byte, 0, len(body)+addition.Len())\n\tout = append(out, body[:insertAt]...)\n\tout = append(out, addition.Bytes()...)\n\tout = append(out, body[insertAt:]...)\n\treturn out, nil","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/providers/jsonsplice/jsonsplice.go#L157-L193","documentation":"AppendObjectFields validates each FieldInsertion: the name must be non-empty and the value must be valid JSON. A blank key or non-JSON value (e.g. a raw string or Go literal) causes the whole splice to fail after partial buffering.","triggerScenarios":"field.Name left as \"\" due to a skipped/conditional config; field.Value built by string concatenation with invalid JSON; passing a bool/int as []byte without marshaling.","commonSituations":"Missing cache breakpoint config producing an empty field name; hand-writing values like ephemeral without quotes; upstream struct serialization disabled or failing silently.","solutions":["Skip empty-named fields before building the insertion list","Always produce field.Value via json.Marshal of the actual value","Add a pre-call loop validating len(field.Name)>0 && json.Valid(field.Value) with a descriptive error"],"exampleFix":"// before: raw value\nfields := []jsonsplice.FieldInsertion{{Name: cfg.Key, Value: []byte(cfg.Val)}}\nout, err := jsonsplice.AppendObjectFields(body, span, fields...)\n// after: marshal value, skip blanks\nvar fields []jsonsplice.FieldInsertion\nfor _, kv := range cfg.Fields() {\n    if kv.Key == \"\" { continue }\n    v, err := json.Marshal(kv.Value)\n    if err != nil { return nil, err }\n    fields = append(fields, jsonsplice.FieldInsertion{Name: kv.Key, Value: v})\n}\nout, err := jsonsplice.AppendObjectFields(body, span, fields...)","handlingStrategy":"validation","validationCode":"for i, f := range fields {\n    if f.Name == \"\" || !json.Valid(f.Value) { return fmt.Errorf(\"field %d invalid: name=%q value=%q\", i, f.Name, f.Value) }\n}","typeGuard":null,"tryCatchPattern":"if err := validateFields(fields); err != nil { return nil, err }\nout, err := jsonsplice.AppendObjectFields(body, span, fields...)","preventionTips":["Build FieldInsertion values with json.Marshal, checking errors","Skip empty-named fields at config load time","Unit-test every field payload with json.Valid"],"tags":["json","go","byte-splice","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}