{"record":{"id":"e59f642d3603eac0","repo":"PrefectHQ/fastmcp","slug":"unsupported-content-type-for-openai-type-item","errorCode":null,"errorMessage":"Unsupported content type for OpenAI: {type(item).__name__}","messagePattern":"Unsupported content type for OpenAI: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/sampling/handlers/openai.py","lineNumber":249,"sourceCode":"                    elif isinstance(item, ToolResultContent):\n                        # Collect tool results (added after assistant message)\n                        content_text = \"\"\n                        if item.content:\n                            result_texts = [\n                                sub_item.text\n                                for sub_item in item.content\n                                if isinstance(sub_item, TextContent)\n                            ]\n                            content_text = \"\\n\".join(result_texts)\n                        tool_messages.append(\n                            ChatCompletionToolMessageParam(\n                                role=\"tool\",\n                                tool_call_id=item.tool_use_id,\n                                content=content_text,\n                            )\n                        )\n                    else:\n                        raise ValueError(\n                            f\"Unsupported content type for OpenAI: {type(item).__name__}\"\n                        )\n\n                # Add assistant message with tool calls if present\n                # OpenAI requires: assistant (with tool_calls) -> tool messages\n                if tool_calls or content_parts:\n                    if tool_calls:\n                        has_multimodal = len(content_parts) > len(text_parts)\n                        if has_multimodal:\n                            raise ValueError(\n                                \"ImageContent/AudioContent is only supported \"\n                                \"in user messages for OpenAI\"\n                            )\n                        text_str = \"\\n\".join(text_parts) or None\n                        openai_messages.append(\n                            ChatCompletionAssistantMessageParam(\n                                role=\"assistant\",\n                                content=text_str,","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/sampling/handlers/openai.py#L231-L267","documentation":"While converting MCP sampling messages to OpenAI format, tool-result messages may only contain text (and resource content that resolves to text); any other content type inside a tool result raises ValueError naming the Python class. This reflects OpenAI's requirement that tool messages carry plain text content.","triggerScenarios":"A sampling message with role='tool' whose content list contains ImageContent, AudioContent, EmbeddedResource with non-text data, etc., passed through _convert_to_openai_messages during Client.sample().","commonSituations":"Tool results that return screenshots or audio clips fed back as tool messages; embedding binary resources in tool output; MCP servers returning rich tool results that OpenAI's tool-message schema can't represent.","solutions":["Convert non-text tool results to text (e.g. describe or caption the image, transcribe audio) before including them.","Move images/audio into a subsequent user message instead of a tool message.","Omit unsupported content items from the tool result.","Use a sampling handler whose provider supports multimodal tool results."],"exampleFix":"// before\nSamplingMessage(role='tool', tool_use_id=id, content=[ImageContent(...)])\n// after\nSamplingMessage(role='tool', tool_use_id=id, content=[TextContent(type='text', text='Tool returned an image (see next message)')])","handlingStrategy":"validation","validationCode":"for m in messages:\n    if m.role == 'tool':\n        for c in m.content:\n            if getattr(c, 'type', None) != 'text':\n                raise ValueError(f\"Tool result contains non-text content: {type(c).__name__}\")","typeGuard":"def is_text_only_tool_result(m) -> bool:\n    return m.role != 'tool' or all(getattr(c, 'type', None) == 'text' for c in m.content)","tryCatchPattern":"try:\n    result = await client.sample(...)\nexcept ValueError as e:\n    if 'Unsupported content type for OpenAI' in str(e):\n        messages = stringify_tool_results(messages)\n        result = await client.sample(messages=messages, ...)\n    else:\n        raise","preventionTips":["Serialize tool outputs to text before returning them as tool messages.","Keep binary/rich tool results out of sampling histories for OpenAI.","Move media to user messages where supported."],"tags":["openai","sampling","content-conversion","tool-calls"],"backgroundTag":"unsupported-media-type","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}