{"record":{"id":"a0d6b3cc72ff1c93","repo":"JuliusBrussee/caveman","slug":"caveman-jsonl-line-d-w","errorCode":null,"errorMessage":"caveman-jsonl line %d: %w","messagePattern":"caveman-jsonl line (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/importers/caveman_jsonl.go","lineNumber":22,"sourceCode":"\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// parseCavemanJSONL parses one JSON span per line. Each line is already close\n// to the Span shape (the same column names), so it unmarshals directly into a\n// Span and then has the authenticated scope stamped over it. Blank lines are\n// skipped. A malformed line aborts the whole import (no partial silent ingest).\nfunc parseCavemanJSONL(data []byte, opts Options) ([]Span, error) {\n\tvar rows []Span\n\tfor i, line := range bytes.Split(data, []byte(\"\\n\")) {\n\t\tline = bytes.TrimSpace(line)\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tvar sp Span\n\t\tif err := json.Unmarshal(line, &sp); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"caveman-jsonl line %d: %w\", i+1, err)\n\t\t}\n\t\tapplyScope(&sp, opts)\n\t\trows = append(rows, sp)\n\t}\n\treturn rows, nil\n}\n","sourceCodeStart":4,"sourceCodeEnd":29,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/importers/caveman_jsonl.go#L4-L29","documentation":"Thrown by parseCavemanJSONL (shared/platform/importers/caveman_jsonl.go:22) when a non-blank line fails json.Unmarshal into the Span shape. The importer deliberately aborts the whole file on the first malformed line - the doc comment states 'no partial silent ingest' - so a single bad line invalidates the batch, and the 1-based line number identifies it.","triggerScenarios":"Importing a .jsonl file where some line is not valid JSON, or is valid JSON whose shape conflicts with the Span struct (wrong types, e.g. a string where a number is expected). Blank/whitespace-only lines are skipped and never trigger this; only lines that attempt unmarshal can fail.","commonSituations":"Log rotation interleaving partial writes into the file; a producer crashing mid-line leaving one truncated JSON line; jq/awk post-processing that dropped a closing brace; mixed formats in one file (CSV header row, exporter banner); NaN/Infinity values that JSON forbids.","solutions":["Open the file at the reported line number and inspect it: head -n N+1 file | tail -1.","Validate every line quickly: awk 'NF{n++}END{print n}' plus jq -c . file > /dev/null to locate all offenders, not just the first.","Remove or fix the malformed lines, then re-run the import (previous attempt ingested nothing).","If a writer is truncating lines, fix its flush/atomic-write behavior (write temp + rename) so imports get complete files."],"exampleFix":"# before (line 42 broken)\n{\"span_id\":\"a1\"...\"trace_id\":\"t\"\n\n# after\n{\"span_id\":\"a1\",\"trace_id\":\"t\"}","handlingStrategy":"validation","validationCode":"// pre-flight the whole file line by line\nfor i, line := range bytes.Split(data, []byte(\"\\n\")) {\n    line = bytes.TrimSpace(line)\n    if len(line) == 0 { continue }\n    if !json.Valid(line) {\n        return fmt.Errorf(\"line %d is not valid JSON; import aborted by design\", i+1)\n    }\n}","typeGuard":"func validJSONL(data []byte) bool {\n    for _, line := range bytes.Split(data, []byte(\"\\n\")) {\n        line = bytes.TrimSpace(line)\n        if len(line) > 0 && !json.Valid(line) { return false }\n    }\n    return true\n}","tryCatchPattern":"spans, err := importers.ImportCavemanJSONL(data, opts)\nif err != nil {\n    return fmt.Errorf(\"import rejected (nothing ingested): %w\", err) // do not retry the same bytes\n}","preventionTips":["Validate JSONL with a jq pass before importing.","Have producers write files atomically so importers never read partial lines.","Keep exporter output homogeneous - one record shape per file."],"tags":["go","import","jsonl","data-validation"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}