PrefectHQ/fastmcp · error · ValueError

Unsupported image MIME type for OpenAI: {content.mime_type!r

Error message

Unsupported image MIME type for OpenAI: {content.mime_type!r}. Supported types: {', '.join(sorted(_OPENAI_IMAGE_MEDIA_TYPES))}

What it means

OpenAI's chat completions image input only supports a fixed set of image MIME types (png/jpeg/webp/gif per _OPENAI_IMAGE_MEDIA_TYPES). When converting MCP ImageContent, an unsupported mime_type raises ValueError listing the supported set.

Source

Thrown at fastmcp_slim/fastmcp/client/sampling/handlers/openai.py:69

# OpenAI only supports wav and mp3 for input audio
_OPENAI_AUDIO_FORMATS: dict[str, Literal["wav", "mp3"]] = {
    "audio/wav": "wav",
    "audio/x-wav": "wav",
    "audio/mp3": "mp3",
    "audio/mpeg": "mp3",
}

_OPENAI_IMAGE_MEDIA_TYPES: frozenset[str] = frozenset(
    {"image/jpeg", "image/png", "image/gif", "image/webp"}
)


def _image_content_to_openai_part(
    content: ImageContent,
) -> ChatCompletionContentPartImageParam:
    """Convert MCP ImageContent to OpenAI image_url content part."""
    if content.mime_type not in _OPENAI_IMAGE_MEDIA_TYPES:
        raise ValueError(
            f"Unsupported image MIME type for OpenAI: {content.mime_type!r}. "
            f"Supported types: {', '.join(sorted(_OPENAI_IMAGE_MEDIA_TYPES))}"
        )
    data_url = f"data:{content.mime_type};base64,{content.data}"
    return ChatCompletionContentPartImageParam(
        type="image_url",
        image_url={"url": data_url},
    )


def _audio_content_to_openai_part(
    content: AudioContent,
) -> ChatCompletionContentPartInputAudioParam:
    """Convert MCP AudioContent to OpenAI input_audio content part."""
    audio_format = _OPENAI_AUDIO_FORMATS.get(content.mime_type)
    if audio_format is None:
        raise ValueError(
            f"Unsupported audio MIME type for OpenAI: {content.mime_type!r}. "

View on GitHub (pinned to 1f02114297)

Solutions

  1. Convert the image to PNG or JPEG before sampling and set mime_type accordingly.
  2. Use a different sampling handler (e.g. the google-genai or anthropic handler) that supports the format.
  3. If the mime_type is missing, set it explicitly to 'image/png' or 'image/jpeg'.
  4. Strip such ImageContent from the message list if it's not essential.

Example fix

// before
ImageContent(type='image', data=raw_tiff_b64, mime_type='image/tiff')
// after
ImageContent(type='image', data=png_b64, mime_type='image/png')
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {'image/png', 'image/jpeg', 'image/webp', 'image/gif'}
for m in messages:
    for c in getattr(m, 'content', []):
        if getattr(c, 'type', None) == 'image' and c.mime_type not in SUPPORTED:
            raise ValueError(f"Convert {c.mime_type} to png/jpeg before OpenAI sampling")

Type guard

def is_openai_supported_image(c) -> bool:
    return getattr(c, 'type', None) == 'image' and c.mime_type in {'image/png','image/jpeg','image/webp','image/gif'}

Try / catch

try:
    result = await client.sample(...)
except ValueError as e:
    if 'Unsupported image MIME type for OpenAI' in str(e):
        messages = transcode_images_to_png(messages)
        result = await client.sample(messages=messages, ...)
    else:
        raise

Prevention

When it happens

Trigger: Client.sample() with ImageContent whose mime_type is e.g. 'image/tiff', 'image/bmp', 'image/svg+xml', or missing/nonstandard, routed to the OpenAI sampling handler via _convert_to_openai_messages -> _image_content_to_openai_part.

Common situations: Resources returning TIFF/BMP screenshots; SVG images from design tools; mime_type omitted or defaulted to something like application/octet-stream; models/providers (o1, some endpoints) that reject formats the library would otherwise allow.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/9dba8f7ac2d8aa5f. Report an issue: GitHub.