PrefectHQ/fastmcp · error · TypeError
The @resource decorator was used incorrectly. It requires a
Error message
The @resource decorator was used incorrectly. It requires a URI as the first argument. Use @resource('uri') instead of @resource What it means
The @resource decorator requires a URI string as its first positional argument. When applied bare as @resource (directly above a function), Python passes the function itself as `uri`; FastMCP detects this (inspect.isroutine) and raises to teach the correct usage.
Source
Thrown at fastmcp_slim/fastmcp/server/providers/local_provider/decorators/resources.py:163
Example:
```python
provider = LocalProvider()
@provider.resource("data://config")
def get_config() -> str:
return '{"setting": "value"}'
@provider.resource("data://{city}/weather")
def get_weather(city: str) -> str:
return f"Weather for {city}"
```
"""
if isinstance(annotations, dict):
annotations = Annotations(**annotations)
if inspect.isroutine(uri):
raise TypeError(
"The @resource decorator was used incorrectly. "
"It requires a URI as the first argument. "
"Use @resource('uri') instead of @resource"
)
def decorator(fn: AnyFunction) -> Any:
# Check for unbound method
try:
params = list(inspect.signature(fn).parameters.keys())
except (ValueError, TypeError):
params = []
if params and params[0] in ("self", "cls"):
fn_name = getattr(fn, "__name__", "function")
raise TypeError(
f"The function '{fn_name}' has '{params[0]}' as its first parameter. "
f"Use the standalone @resource decorator and register the bound method:\n\n"
f" from fastmcp.resources import resource\n\n"
f" class MyClass:\n"View on GitHub (pinned to 1f02114297)
Solutions
- Add the URI argument: use @resource('your-scheme://your-uri') instead of @resource.
- If configuration is needed, use @resource('uri', name=..., description=...) — parentheses are mandatory.
Example fix
// before
@resource
def get_config() -> str:
...
// after
@resource('config://app')
def get_config() -> str:
... Defensive patterns
Strategy: validation
Validate before calling
uri = 'config://app'
if not isinstance(uri, str):
raise TypeError('first arg to @resource must be a URI string')
@resource(uri)
def get_config() -> str:
... Type guard
def has_uri_args(decorated) -> bool:
return callable(decorated) and not inspect.isroutine(decorated) Try / catch
try:
mcp.add_resource(my_fn)
except TypeError as e:
if 'requires a URI' in str(e):
raise ValueError('forgot the URI: use @resource("uri")') from e
raise Prevention
- Remember @resource always needs a URI, unlike @tool which supports bare usage.
- Lint for bare @resource lines in code review.
- Keep the URI scheme in a constant to avoid typo'd decorator usage.
When it happens
Trigger: Writing `@resource` instead of `@resource('scheme://path')` above a function, then registering it on a FastMCP instance.
Common situations: Copying the @tool pattern (which supports bare @tool) and applying it to @resource, which always requires a URI; typos when converting a plain function into a resource.
Related errors
- Expected Resource, ResourceTemplate, or @resource-decorated
- The function '{fn_name}' has '{params[0]}' as its first para
- 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
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/7c7759a7cf2765db.
Report an issue: GitHub.