PrefectHQ/fastmcp · error · TypeError
contents[{i}] must be ResourceContent, got {type(item).__nam
Error message
contents[{i}] must be ResourceContent, got {type(item).__name__}. Use ResourceContent({item!r}) to wrap the value. What it means
ResourceResult._normalize_contents accepts str, bytes, or a list of ResourceContent objects. When you pass a list, every element must already be a ResourceContent instance; a plain str/int/dict inside the list triggers this TypeError. Unlike a bare JSON-native value, lists are not auto-wrapped element-wise because mixed content (text + binary) requires explicit types.
Source
Thrown at fastmcp_slim/fastmcp/resources/base.py:182
meta: Optional metadata about the resource result.
"""
normalized = self._normalize_contents(contents)
super().__init__(contents=normalized, meta=meta)
@staticmethod
def _normalize_contents(
contents: str | bytes | list[ResourceContent],
) -> list[ResourceContent]:
"""Normalize input to list[ResourceContent]."""
if isinstance(contents, str):
return [ResourceContent(contents)]
if isinstance(contents, bytes):
return [ResourceContent(contents)]
if isinstance(contents, list):
# Validate all items are ResourceContent
for i, item in enumerate(contents):
if not isinstance(item, ResourceContent):
raise TypeError(
f"contents[{i}] must be ResourceContent, got {type(item).__name__}. "
f"Use ResourceContent({item!r}) to wrap the value."
)
return contents
# Auto-serialize JSON-native types to JSON text
if (
isinstance(contents, dict | list | tuple | int | float | bool)
or contents is None
):
return [ResourceContent(json.dumps(contents), mime_type="application/json")]
raise TypeError(
f"contents must be str, bytes, or list[ResourceContent], got {type(contents).__name__}"
)
def to_mcp_result(self, uri: AnyUrl | str) -> mcp_types.ReadResourceResult:
"""Convert to MCP ReadResourceResult.
Args:View on GitHub (pinned to 1f02114297)
Solutions
- Wrap each list element in ResourceContent: contents=[ResourceContent(s) for s in strings]
- If the whole value is a single JSON-native value (dict/int/None etc.), pass it directly instead of a list — it will be auto-serialized with mime_type application/json
- If the item is already a TextResource/other content object, convert via its text/bytes into ResourceContent
Example fix
// before
return ResourceResult(contents=["hello", b"bin"])
// after
return ResourceResult(contents=[ResourceContent("hello"), ResourceContent(b"bin")]) Defensive patterns
Strategy: type-guard
Validate before calling
def is_valid_contents(c):
return isinstance(c, (str, bytes)) or (
isinstance(c, list) and all(isinstance(i, ResourceContent) for i in c)
)
assert is_valid_contents(my_contents) Type guard
def as_content_list(items) -> list[ResourceContent]:
return [i if isinstance(i, ResourceContent) else ResourceContent(i) for i in items] Try / catch
try:
result = ResourceResult(contents=items)
except TypeError as e:
items = [ResourceContent(i) for i in items]
result = ResourceResult(contents=items) Prevention
- Always wrap list elements in ResourceContent when constructing ResourceResult
- Pass single JSON-native values bare (dict/int/None) to get auto JSON serialization
- Add a unit test asserting resource functions return valid contents types
When it happens
Trigger: ResourceResult(contents=["plain string"]); ResourceResult(contents=[b'bytes']); ResourceResult(contents=[{"a":1}]) — any list containing raw values instead of ResourceContent objects, e.g. returned from a @mcp.resource function body.
Common situations: Developers migrating from APIs that accepted raw strings/bytes lists, or returning [item1, item2] from multiple fetches without wrapping each in ResourceContent. Also common when the wrap-suggestion in the message is copy-pasted but the value is a dict whose repr isn't valid code.
Related errors
- contents must be str, bytes, or list[ResourceContent], got {
- Expected Resource, ResourceTemplate, or @resource-decorated
- ResourcesAsTools requires a FastMCP server instance, not a {
- Protocol mode for server {name!r} must be a string
- mcp_tool() got unexpected keyword argument(s): {sorted(unkno
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/684ba03903844aae.
Report an issue: GitHub.