{"record":{"id":"e4d43ceec4280270","repo":"wavetermdev/waveterm","slug":"all-d-image-conversions-failed","errorCode":null,"errorMessage":"all %d image conversions failed","messagePattern":"all (.+?) image conversions failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-convertmessage.go","lineNumber":443,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\tif strings.HasPrefix(part.MimeType, \"image/\") {\n\t\t\t\t\timageFailCount++\n\t\t\t\t}\n\t\t\t\tlog.Printf(\"openai: %v\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcontentBlocks = append(contentBlocks, *block)\n\n\t\tdefault:\n\t\t\t// Drop unknown part types\n\t\t\tlog.Printf(\"openai: dropping unknown part type '%s'\", part.Type)\n\t\t\tcontinue\n\t\t}\n\t}\n\n\tif len(contentBlocks) == 0 {\n\t\tif imageCount > 0 && imageFailCount == imageCount {\n\t\t\treturn nil, fmt.Errorf(\"all %d image conversions failed\", imageCount)\n\t\t}\n\t\treturn nil, errors.New(\"message has no valid content after processing all parts\")\n\t}\n\n\treturn &OpenAIChatMessage{\n\t\tMessageId: aiMsg.MessageId,\n\t\tMessage: &OpenAIMessage{\n\t\t\tRole:    \"user\",\n\t\t\tContent: contentBlocks,\n\t\t},\n\t}, nil\n}\n\n// ConvertToolResultsToOpenAIChatMessage converts AIToolResult slice to OpenAIChatMessage slice\nfunc ConvertToolResultsToOpenAIChatMessage(toolResults []uctypes.AIToolResult) ([]*OpenAIChatMessage, error) {\n\tif len(toolResults) == 0 {\n\t\treturn nil, errors.New(\"toolResults cannot be empty\")\n\t}","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-convertmessage.go#L425-L461","documentation":"After processing all parts, if every content block was an image and every image failed to convert (imageFailCount == imageCount), the message would have no usable content, so the converter returns this error reporting how many images failed. It distinguishes total image-conversion failure from the generic 'no valid content' case.","triggerScenarios":"An AIMessage containing only image parts where each image part fails conversion (e.g. unreadable/invalid image data, unsupported format, failed base64/data-URL decode), leaving len(contentBlocks)==0.","commonSituations":"Sending corrupt or truncated image files; images whose data URLs are malformed; image sources that failed to load upstream so the bytes are empty; unsupported encodings after a library upgrade.","solutions":["Log the per-image conversion failures (the loop counts imageFailCount) to find the root cause","Validate/decode image data before adding image parts to the AIMessage","Include at least one text part alongside images so a single image failure doesn't void the message","Re-encode the images to a supported format (e.g. PNG/JPEG base64 data URL)"],"exampleFix":"// before\nmsg := uctypes.AIMessage{Parts: []uctypes.AIMessagePart{{Type: uctypes.AIMessagePartTypeImage, /* corrupt data */}}}\n// after\nmsg := uctypes.AIMessage{Parts: []uctypes.AIMessagePart{\n    {Type: uctypes.AIMessagePartTypeText, Text: \"describe the image\"},\n    {Type: uctypes.AIMessagePartTypeImage, /* valid base64 data */},\n}}","handlingStrategy":"fallback","validationCode":"validImages := 0\nfor _, p := range aiMsg.Parts {\n    if p.Type == uctypes.AIMessagePartTypeImage && imageDecodes(p) { validImages++ }\n}","typeGuard":null,"tryCatchPattern":"out, err := ConvertAIMessageToOpenAIChatMessage(msg)\nif err != nil && strings.Contains(err.Error(), \"image conversions failed\") {\n    // fall back to a text-only message or surface image errors to the user\n}","preventionTips":["Keep a text part alongside images","Validate image data URLs / base64 before adding image parts","Log per-image conversion failures during the conversion loop"],"tags":["openai","image-processing","validation"],"backgroundTag":"image-conversion-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}