{"record":{"id":"cd5b916502fc1a70","repo":"JuliusBrussee/caveman","slug":"otlp-decode-w","errorCode":null,"errorMessage":"otlp decode: %w","messagePattern":"otlp decode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/importers/otlp.go","lineNumber":89,"sourceCode":"}\n\ntype otlpEvent struct {\n\tName         string   `json:\"name\"`\n\tTimeUnixNano string   `json:\"timeUnixNano\"`\n\tAttributes   []otlpKV `json:\"attributes\"`\n}\n\ntype otlpStatus struct {\n\tCode    int    `json:\"code\"`\n\tMessage string `json:\"message\"`\n}\n\n// parseOTLP decodes an OTLP/JSON trace payload and maps GenAI semantic\n// conventions to Span columns. On a JSON error it returns no rows.\nfunc parseOTLP(data []byte, opts Options) ([]Span, error) {\n\tvar p otlpPayload\n\tif err := json.Unmarshal(data, &p); err != nil {\n\t\treturn nil, fmt.Errorf(\"otlp decode: %w\", err)\n\t}\n\tvar rows []Span\n\tfor _, rs := range p.ResourceSpans {\n\t\tresAttrs := otlpKVMap(rs.Resource.Attributes)\n\t\tfor _, ss := range rs.ScopeSpans {\n\t\t\tfor _, sp := range ss.Spans {\n\t\t\t\trows = append(rows, mapOTLPSpan(sp, resAttrs, opts))\n\t\t\t}\n\t\t}\n\t}\n\treturn rows, nil\n}\n\nfunc mapOTLPSpan(sp otlpSpan, resAttrs map[string]string, opts Options) Span {\n\tattrs := otlpKVMap(sp.Attributes)\n\n\tgenAI := telemetry.ExtractGenAIFields(attrs, resAttrs, sp.Name)\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/importers/otlp.go#L71-L107","documentation":"parseOTLP wraps any json.Unmarshal failure of an OTLP/JSON trace payload with the \"otlp decode: \" prefix and returns no rows. The library throws it because the payload bytes are not valid JSON or do not match the expected otlpPayload structure (resourceSpans/scopeSpans/spans hierarchy). It guarantees callers get an error instead of silently decoding a partial or empty result.","triggerScenarios":"Calling Parse/parseOTLP with bytes that are not valid JSON, truncated payloads, wrong content type (e.g. protobuf OTLP binary passed where OTLP/JSON is expected), or JSON with incompatible field types (e.g. traceId as number instead of string).","commonSituations":"Fetching traces from a collector endpoint that emits protobuf instead of JSON; reading a truncated or corrupted export file; ingesting output of a tool that logs non-JSON lines; schema drift after an OTLP version change (renamed or restructured fields).","solutions":["Validate the payload is complete JSON before calling Parse (e.g. json.Valid(data)).","Confirm the exporter emits OTLP/JSON, not OTLP/protobuf; convert or request JSON format.","Log a snippet of the failing bytes around the JSON error offset to spot truncation or encoding issues.","Ensure the source encodes fields with types matching the OTLP/JSON spec (hex string IDs, string attributes)."],"exampleFix":"// before\nrows, err := Parse(body) // \"otlp decode: unexpected end of JSON input\"\n// after\nif !json.Valid(body) {\n    return fmt.Errorf(\"payload is not valid JSON (len=%d)\", len(body))\n}\nrows, err := Parse(body)","handlingStrategy":"validation","validationCode":"if len(data) == 0 || !json.Valid(data) {\n    return fmt.Errorf(\"otlp payload is not valid JSON (len=%d)\", len(data))\n}","typeGuard":null,"tryCatchPattern":"rows, err := Parse(data)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"otlp decode:\") {\n        return fmt.Errorf(\"invalid OTLP/JSON payload: %w\", err)\n    }\n    return err\n}","preventionTips":["Run json.Valid on payloads before parsing.","Ensure exporters emit OTLP/JSON, not protobuf.","Checksum or size-check trace files before ingestion.","Pin OTLP exporter/library versions to avoid schema drift."],"tags":["go","json","otlp","tracing","decode"],"backgroundTag":"json-decode-failed","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"}