PrefectHQ/fastmcp · error · TypeError
Expected Resource, ResourceTemplate, or @resource-decorated
Error message
Expected Resource, ResourceTemplate, or @resource-decorated function, got {type(resource).__name__}. Use @resource('uri') decorator or pass a Resource/ResourceTemplate instance. What it means
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.
Source
Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/decorators/resources.py:93
security=meta.security,
)
else:
resource = Resource.from_function(
fn=resource,
uri=meta.uri,
name=meta.name,
version=meta.version,
title=meta.title,
description=meta.description,
icons=meta.icons,
mime_type=meta.mime_type,
tags=meta.tags,
annotations=meta.annotations,
meta=meta.meta,
auth=meta.auth,
)
else:
raise TypeError(
f"Expected Resource, ResourceTemplate, or @resource-decorated function, got {type(resource).__name__}. "
"Use @resource('uri') decorator or pass a Resource/ResourceTemplate instance."
)
self._add_component(resource)
if not enabled:
self.disable(keys={resource.key})
return resource
def add_template(
self: LocalProvider, template: ResourceTemplate
) -> ResourceTemplate:
"""Add a resource template to this provider's storage."""
return self._add_component(template)
def resource(
self: LocalProvider,
uri: str,
*,View on GitHub (pinned to 1f02114297)
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.
Example fix
// before
mcp.add_resource(get_config)
// after
from fastmcp.resources import resource
@resource('config://app')
def get_config() -> str:
...
mcp.add_resource(get_config) Defensive patterns
Strategy: type-guard
Validate before calling
from fastmcp.resources import Resource, ResourceTemplate
import inspect
def can_register(obj) -> bool:
return isinstance(obj, (Resource, ResourceTemplate)) or (
inspect.isroutine(obj) and getattr(obj, '__fastmcp__', None) is not None
)
assert can_register(candidate), 'decorate with @resource first'
mcp.add_resource(candidate) Type guard
def is_registerable_resource(obj) -> bool:
from fastmcp.resources import Resource, ResourceTemplate
return isinstance(obj, (Resource, ResourceTemplate)) or (
callable(obj) and hasattr(obj, '__fastmcp__')
) Try / catch
try:
mcp.add_resource(obj)
except TypeError as e:
if 'Expected Resource' in str(e):
obj = resource('my-scheme://uri')(obj)
mcp.add_resource(obj)
else:
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- mcp_tool() got unexpected keyword argument(s): {sorted(unkno
- mcp_resource() got unexpected keyword argument(s): {sorted(u
- mcp_prompt() got unexpected keyword argument(s): {sorted(unk
- contents[{i}] must be ResourceContent, got {type(item).__nam
- contents must be str, bytes, or list[ResourceContent], got {
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/77e2861d85712fdc.
Report an issue: GitHub.