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
- Inspect the message and convert unsupported content to TextContent (e.g. serialize the resource) before sampling.
- Check MCP SDK versions on client and server match so both sides agree on content types.
- Add a pre-conversion step that strips or flattens unknown content types from SamplingMessage.content lists.
- 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
- Convert EmbeddedResource and custom content to TextContent before sampling
- Pin matching MCP SDK versions on client and server
- Filter unknown content types in a middleware layer
- Keep an allowlist of content types for each provider handler
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
- Unsupported content type for OpenAI: {type(item).__name__}
- ImageContent/AudioContent is only supported in user messages
- Unsupported image MIME type for OpenAI: {content.mime_type!r
- Unsupported audio MIME type for OpenAI: {content.mime_type!r
- ImageContent is only supported in user messages for OpenAI
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/926e69db05c563e1.
Report an issue: GitHub.