PrefectHQ/fastmcp · error · ValueError

Unsupported content type: {type(content)}

Error message

Unsupported content type: {type(content)}

What it means

The message converter handles ToolUseContent, ToolResultContent, TextContent, ImageContent, and AudioContent. Any other content item type in a SamplingMessage falls through all isinstance checks and raises this ValueError naming the offending type.

Source

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

                    )
                )
                continue

            # Handle AudioContent
            if isinstance(content, AudioContent):
                if message.role != "user":
                    raise ValueError(
                        "AudioContent is only supported in user messages for OpenAI"
                    )
                openai_messages.append(
                    ChatCompletionUserMessageParam(
                        role="user",
                        content=[_audio_content_to_openai_part(content)],
                    )
                )
                continue

            raise ValueError(f"Unsupported content type: {type(content)}")

        return openai_messages

    @staticmethod
    def _chat_completion_to_create_message_result(
        chat_completion: ChatCompletion,
    ) -> CreateMessageResult:
        if len(chat_completion.choices) == 0:
            raise ValueError("No response for completion")

        first_choice = chat_completion.choices[0]

        if content := first_choice.message.content:
            return CreateMessageResult(
                content=TextContent(type="text", text=content),
                role="assistant",
                model=chat_completion.model,
            )

View on GitHub (pinned to 1f02114297)

Solutions

  1. Inspect the message and convert unsupported content to TextContent (e.g. serialize the resource) before sampling.
  2. Check MCP SDK versions on client and server match so both sides agree on content types.
  3. Add a pre-conversion step that strips or flattens unknown content types from SamplingMessage.content lists.
  4. Catch ValueError, log type(content), and degrade gracefully to text-only sampling.

Example fix

// before
SamplingMessage(role='user', content=[EmbeddedResource(resource=...), TextContent(...)])
// after
SamplingMessage(role='user', content=[TextContent(type='text', text=resource_to_text(resource)), TextContent(...)])
Defensive patterns

Strategy: type-guard

Validate before calling

SUPPORTED = (TextContent, ImageContent, AudioContent, ToolUseContent, ToolResultContent)
def assert_supported_content(messages):
    for m in messages:
        for c in m.content:
            if not isinstance(c, SUPPORTED):
                raise ValueError(f'Content type {type(c).__name__} unsupported by OpenAI handler')

Type guard

from mcp.types import Content
SUPPORTED = (TextContent, ImageContent, AudioContent, ToolUseContent, ToolResultContent)
def is_supported_content(c: Content) -> bool:
    return isinstance(c, SUPPORTED)

Try / catch

try:
    result = await openai_handler(messages, params)
except ValueError as e:
    if str(e).startswith('Unsupported content type:'):
        messages = flatten_to_text(messages)  # serialize/convert unknown parts
        result = await openai_handler(messages, params)
    else:
        raise

Prevention

When it happens

Trigger: A SamplingMessage whose content list contains a content type not in the supported set (e.g. a custom or newly added MCP content class, EmbeddedResource, or a None) is passed to the OpenAI sampling handler.

Common situations: MCP SDK version mismatches introducing new content types the handler doesn't know; custom content subclasses from server-side middleware; passing ResourceContents or embedded resources directly instead of converting them to TextContent/ImageContent first.

Related errors


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