{"record":{"id":"684ba03903844aae","repo":"PrefectHQ/fastmcp","slug":"contents-i-must-be-resourcecontent-got-type-i","errorCode":null,"errorMessage":"contents[{i}] must be ResourceContent, got {type(item).__name__}. Use ResourceContent({item!r}) to wrap the value.","messagePattern":"contents\\[(.+?)\\] must be ResourceContent, got (.+?)\\. Use ResourceContent\\((.+?)\\) to wrap the value\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/resources/base.py","lineNumber":182,"sourceCode":"            meta: Optional metadata about the resource result.\n        \"\"\"\n        normalized = self._normalize_contents(contents)\n        super().__init__(contents=normalized, meta=meta)\n\n    @staticmethod\n    def _normalize_contents(\n        contents: str | bytes | list[ResourceContent],\n    ) -> list[ResourceContent]:\n        \"\"\"Normalize input to list[ResourceContent].\"\"\"\n        if isinstance(contents, str):\n            return [ResourceContent(contents)]\n        if isinstance(contents, bytes):\n            return [ResourceContent(contents)]\n        if isinstance(contents, list):\n            # Validate all items are ResourceContent\n            for i, item in enumerate(contents):\n                if not isinstance(item, ResourceContent):\n                    raise TypeError(\n                        f\"contents[{i}] must be ResourceContent, got {type(item).__name__}. \"\n                        f\"Use ResourceContent({item!r}) to wrap the value.\"\n                    )\n            return contents\n        # Auto-serialize JSON-native types to JSON text\n        if (\n            isinstance(contents, dict | list | tuple | int | float | bool)\n            or contents is None\n        ):\n            return [ResourceContent(json.dumps(contents), mime_type=\"application/json\")]\n        raise TypeError(\n            f\"contents must be str, bytes, or list[ResourceContent], got {type(contents).__name__}\"\n        )\n\n    def to_mcp_result(self, uri: AnyUrl | str) -> mcp_types.ReadResourceResult:\n        \"\"\"Convert to MCP ReadResourceResult.\n\n        Args:","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/resources/base.py#L164-L200","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nreturn ResourceResult(contents=[\"hello\", b\"bin\"])\n// after\nreturn ResourceResult(contents=[ResourceContent(\"hello\"), ResourceContent(b\"bin\")])","handlingStrategy":"type-guard","validationCode":"def is_valid_contents(c):\n    return isinstance(c, (str, bytes)) or (\n        isinstance(c, list) and all(isinstance(i, ResourceContent) for i in c)\n    )\nassert is_valid_contents(my_contents)","typeGuard":"def as_content_list(items) -> list[ResourceContent]:\n    return [i if isinstance(i, ResourceContent) else ResourceContent(i) for i in items]","tryCatchPattern":"try:\n    result = ResourceResult(contents=items)\nexcept TypeError as e:\n    items = [ResourceContent(i) for i in items]\n    result = ResourceResult(contents=items)","preventionTips":["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"],"tags":["python","resources","type-error"],"backgroundTag":"invalid-content-type","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}