{"record":{"id":"8905fcf47a469b30","repo":"JuliusBrussee/caveman","slug":"inline-data-w","errorCode":null,"errorMessage":"inline_data: %w","messagePattern":"inline_data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/pixel/transform_gemini.go","lineNumber":358,"sourceCode":"}\n\nfunc (p *geminiPart) UnmarshalJSON(data []byte) error {\n\tvar raw map[string]json.RawMessage\n\tif err := json.Unmarshal(data, &raw); err != nil {\n\t\treturn err\n\t}\n\tp.Extra = raw\n\tif v, ok := raw[\"text\"]; ok {\n\t\tvar s string\n\t\tif err := json.Unmarshal(v, &s); err != nil {\n\t\t\treturn fmt.Errorf(\"text: %w\", err)\n\t\t}\n\t\tp.Text = &s\n\t}\n\tif v, ok := raw[\"inline_data\"]; ok {\n\t\tvar inline geminiInlineData\n\t\tif err := json.Unmarshal(v, &inline); err != nil {\n\t\t\treturn fmt.Errorf(\"inline_data: %w\", err)\n\t\t}\n\t\tp.InlineData = &inline\n\t}\n\tif v, ok := raw[\"functionResponse\"]; ok {\n\t\tvar fr geminiFunctionResponse\n\t\tif err := json.Unmarshal(v, &fr); err != nil {\n\t\t\treturn fmt.Errorf(\"functionResponse: %w\", err)\n\t\t}\n\t\tp.FunctionResponse = &fr\n\t}\n\tif v, ok := raw[\"functionCall\"]; ok {\n\t\tvar fc geminiFunctionCall\n\t\tif err := json.Unmarshal(v, &fc); err != nil {\n\t\t\treturn fmt.Errorf(\"functionCall: %w\", err)\n\t\t}\n\t\tp.FunctionCall = &fc\n\t}\n\treturn nil","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/pixel/transform_gemini.go#L340-L376","documentation":"The same custom UnmarshalJSON decodes the \"inline_data\" key into a geminiInlineData struct (mimeType/data). If \"inline_data\" is present but has the wrong shape — mistyped or missing mimeType/data fields, or a non-object value — the unmarshal error is wrapped as \"inline_data: %w\" and the part fails to decode.","triggerScenarios":"Unmarshaling a part containing \"inline_data\" that is not a valid {mimeType, data} object — e.g. \"inline_data\": \"base64string\" (bare string), or an object with \"data\" as a non-string.","commonSituations":"Clients using camelCase \"inlineData\" mixed with snake_case fields or nesting mismatch; attachments encoded without base64 string typing; fixtures ported from other multimodal providers.","solutions":["Send inline_data as an object with string fields: {\"inline_data\": {\"mimeType\": \"image/png\", \"data\": \"<base64>\"}}.","Verify the base64 payload is a JSON string, not raw bytes or an object.","Check key naming consistency (snake_case inline_data vs camelCase inlineData) matches what the transform expects."],"exampleFix":"// before\n{\"inline_data\": \"iVBORw0KGgo...\"}\n// after\n{\"inline_data\": {\"mimeType\": \"image/png\", \"data\": \"iVBORw0KGgo...\"}}","handlingStrategy":"validation","validationCode":"var probe struct {\n    Parts []struct {\n        InlineData *struct {\n            MimeType string `json:\"mimeType\"`\n            Data     string `json:\"data\"`\n        } `json:\"inline_data\"`\n    } `json:\"parts\"`\n}\nif err := json.Unmarshal(body, &probe); err != nil {\n    return fmt.Errorf(\"inline_data must be {mimeType: string, data: string}\")\n}","typeGuard":"func validInlineData(part map[string]json.RawMessage) bool {\n    v, ok := part[\"inline_data\"]\n    if !ok {\n        return true\n    }\n    var in struct {\n        MimeType string `json:\"mimeType\"`\n        Data     string `json:\"data\"`\n    }\n    return json.Unmarshal(v, &in) == nil\n}","tryCatchPattern":"var req geminiGenerateContent\nif err := json.Unmarshal(body, &req); err != nil {\n    if strings.Contains(err.Error(), \"inline_data:\") {\n        return fmt.Errorf(\"inline_data must be an object with string mimeType and base64 data: %w\", err)\n    }\n    return err\n}","preventionTips":["Send inline_data as {\"mimeType\": \"<type>\", \"data\": \"<base64 string>\"} — both fields strings.","Keep key naming consistent (inline_data vs inlineData) with what the transform struct expects.","Pre-validate attachments with a small probe struct before full unmarshal."],"tags":["gemini","json","unmarshal","schema"],"backgroundTag":"json-unmarshal-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"}