{"record":{"id":"77e2861d85712fdc","repo":"PrefectHQ/fastmcp","slug":"expected-resource-resourcetemplate-or-resource","errorCode":null,"errorMessage":"Expected Resource, ResourceTemplate, or @resource-decorated function, got {type(resource).__name__}. Use @resource('uri') decorator or pass a Resource/ResourceTemplate instance.","messagePattern":"Expected Resource, ResourceTemplate, or @resource-decorated function, got (.+?)\\. Use @resource\\('uri'\\) decorator or pass a Resource/ResourceTemplate instance\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/providers/local_provider/decorators/resources.py","lineNumber":93,"sourceCode":"                        security=meta.security,\n                    )\n                else:\n                    resource = Resource.from_function(\n                        fn=resource,\n                        uri=meta.uri,\n                        name=meta.name,\n                        version=meta.version,\n                        title=meta.title,\n                        description=meta.description,\n                        icons=meta.icons,\n                        mime_type=meta.mime_type,\n                        tags=meta.tags,\n                        annotations=meta.annotations,\n                        meta=meta.meta,\n                        auth=meta.auth,\n                    )\n            else:\n                raise TypeError(\n                    f\"Expected Resource, ResourceTemplate, or @resource-decorated function, got {type(resource).__name__}. \"\n                    \"Use @resource('uri') decorator or pass a Resource/ResourceTemplate instance.\"\n                )\n        self._add_component(resource)\n        if not enabled:\n            self.disable(keys={resource.key})\n        return resource\n\n    def add_template(\n        self: LocalProvider, template: ResourceTemplate\n    ) -> ResourceTemplate:\n        \"\"\"Add a resource template to this provider's storage.\"\"\"\n        return self._add_component(template)\n\n    def resource(\n        self: LocalProvider,\n        uri: str,\n        *,","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/providers/local_provider/decorators/resources.py#L75-L111","documentation":"FastMCP's add_resource() accepts only a Resource instance, a ResourceTemplate instance, or a function already decorated with @resource. The argument passed had some other type, so the server cannot turn it into a registerable resource component and aborts with a TypeError naming the offending type.","triggerScenarios":"Calling mcp.add_resource() with a bare undecorated function, a method, a string URI, a dict, a functools.partial, or a class instead of a Resource/ResourceTemplate/@resource-decorated function.","commonSituations":"Migrating from older FastMCP APIs where add_resource(fn, uri=...) auto-wrapped functions; copying examples that show @resource but forgetting to apply the decorator; passing the result of a function call instead of the resource object itself.","solutions":["Decorate the function with @resource('uri') and register the decorated result.","If you already have a function, construct an explicit FunctionResource and pass that.","For dynamic URI patterns, create a ResourceTemplate instead and add it via add_template/add_resource."],"exampleFix":"// before\nmcp.add_resource(get_config)\n\n// after\nfrom fastmcp.resources import resource\n\n@resource('config://app')\ndef get_config() -> str:\n    ...\n\nmcp.add_resource(get_config)","handlingStrategy":"type-guard","validationCode":"from fastmcp.resources import Resource, ResourceTemplate\nimport inspect\n\ndef can_register(obj) -> bool:\n    return isinstance(obj, (Resource, ResourceTemplate)) or (\n        inspect.isroutine(obj) and getattr(obj, '__fastmcp__', None) is not None\n    )\n\nassert can_register(candidate), 'decorate with @resource first'\nmcp.add_resource(candidate)","typeGuard":"def is_registerable_resource(obj) -> bool:\n    from fastmcp.resources import Resource, ResourceTemplate\n    return isinstance(obj, (Resource, ResourceTemplate)) or (\n        callable(obj) and hasattr(obj, '__fastmcp__')\n    )","tryCatchPattern":"try:\n    mcp.add_resource(obj)\nexcept TypeError as e:\n    if 'Expected Resource' in str(e):\n        obj = resource('my-scheme://uri')(obj)\n        mcp.add_resource(obj)\n    else:\n        raise","preventionTips":["Always decorate functions with @resource('uri') before passing to add_resource.","Never pass raw functions, strings, or dicts to add_resource.","Use add_template for URI templates rather than hand-built objects."],"tags":["python","fastmcp","resources","type-error"],"backgroundTag":"invalid-resource-registration","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}