deepset-ai/haystack · error · ValueError

Unsupported content type: {type(part)}

Error message

Unsupported content type: {type(part)}

What it means

When converting a ChatMessage to the OpenAI Responses API format, each content part must be a known type (text, image, file). `convert_part` raises ValueError for any unrecognized content part class, meaning the message contains a content type haystack cannot map to the Responses API.

Source

Thrown at haystack/components/generators/chat/openai_responses.py:986

    def convert_part(part: Any) -> dict[str, str | None]:
        if isinstance(part, TextContent):
            return {"type": "input_text", "text": part.text}
        if isinstance(part, ImageContent):
            return {
                "type": "input_image",
                # If no MIME type is provided, default to JPEG. OpenAI API appears to tolerate MIME type mismatches.
                "image_url": f"data:{part.mime_type or 'image/jpeg'};base64,{part.base64_image}",
            }
        if isinstance(part, FileContent):
            return {
                "type": "input_file",
                # Filename is optional but if not provided, OpenAI expects a file_id of a previous file upload.
                # We use a dummy filename to avoid this issue.
                "filename": part.filename or "filename",
                "file_data": f"data:{part.mime_type or 'application/pdf'};base64,{part.base64_data}",
            }
        raise ValueError(f"Unsupported content type: {type(part)}")

    text_contents = message.texts
    tool_calls = message.tool_calls
    tool_call_results = message.tool_call_results
    images = message.images
    reasonings = message.reasonings
    files = message.files

    if not any([text_contents, tool_calls, tool_call_results, images, reasonings, files]):
        raise ValueError(
            """A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`,
              `ImageContent`, `FileContent`, or `ReasoningContent`."""
        )
    if len(tool_call_results) > 0 and len(message._content) > 1:
        raise ValueError(
            "For OpenAI compatibility, a `ChatMessage` with a `ToolCallResult` cannot contain any other content."
        )

View on GitHub (pinned to e318778c9b)

Solutions

  1. Remove unsupported content parts from the message before calling the generator
  2. Convert unsupported parts to TextContent/FileContent/ImageContent equivalents
  3. Inspect `message._content` types and filter to supported types

Example fix

// before
msg = ChatMessage(_role=ChatRole.USER, _content=[unsupported_part])
// after
msg = ChatMessage.from_user("text equivalent of the content")
Defensive patterns

Strategy: validation

Validate before calling

from haystack.dataclasses import TextContent, ImageContent, FileContent
allowed = (TextContent, ImageContent, FileContent)
for m in messages:
    assert all(isinstance(p, allowed) for p in m._content), [type(p) for p in m._content]

Type guard

def is_supported_part(p) -> bool:
    from haystack.dataclasses import TextContent, ImageContent, FileContent
    return isinstance(p, (TextContent, ImageContent, FileContent))

Try / catch

try:
    gen.run(messages=messages)
except ValueError as e:
    if "Unsupported content type" in str(e):
        messages = [filter_supported(m) for m in messages]

Prevention

When it happens

Trigger: A ChatMessage whose _content contains a part type not handled by convert_part — e.g. a custom/ReasoningContent part or an unexpected content class in a message passed to OpenAIResponsesChatGenerator.

Common situations: Messages built programmatically with custom content parts; passing messages produced by other backends (e.g. reasoning traces) directly to the Responses API converter.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/02d396744625fa1f. Report an issue: GitHub.