PrefectHQ/fastmcp · error · NotImplementedError
Subclasses must implement create_resource(). Use FunctionRes
Error message
Subclasses must implement create_resource(). Use FunctionResourceTemplate for task support.
What it means
ResourceTemplate.create_resource() materializes a concrete Resource from a matched URI and parameters; the base implementation deliberately does not support it (background-task-capable reads require create_resource, which only FunctionResourceTemplate provides). Subclasses must either implement it or not rely on the code path that calls it.
Source
Thrown at fastmcp_slim/fastmcp/resources/template.py:302
async def _read(self, uri: str, params: dict[str, Any]) -> ResourceResult:
"""Server entry point for template reads.
The server calls this instead of create_resource()/read() directly so
subclasses can customize dispatch (e.g. FastMCPProviderResourceTemplate
delegates to child-server middleware).
"""
resource = await self.create_resource(uri, params)
result = await resource.read()
return self.convert_result(result)
async def create_resource(self, uri: str, params: dict[str, Any]) -> Resource:
"""Create a resource from the template with the given parameters.
The base implementation does not support background tasks.
Use FunctionResourceTemplate for task support.
"""
raise NotImplementedError(
"Subclasses must implement create_resource(). "
"Use FunctionResourceTemplate for task support."
)
def to_mcp_template(
self,
**overrides: Any,
) -> SDKResourceTemplate:
"""Convert the resource template to an SDKResourceTemplate."""
return SDKResourceTemplate(
name=overrides.get("name", self.name),
uri_template=overrides.get("uriTemplate", self.uri_template),
description=overrides.get("description", self.description),
mime_type=overrides.get("mimeType", self.mime_type),
title=overrides.get("title", self.title),
icons=overrides.get("icons", self.icons),
annotations=overrides.get("annotations", self.annotations),View on GitHub (pinned to 1f02114297)
Solutions
- Implement async def create_resource(self, uri, params) returning a configured Resource instance
- Or subclass FunctionResourceTemplate, which provides a working create_resource for functions
- If you only need simple reads and no tasks, ensure your code path calls read() directly, not create_resource()
Example fix
// before
class T(ResourceTemplate):
async def read(self, args): return "data"
// after
class T(ResourceTemplate):
async def read(self, args): return "data"
async def create_resource(self, uri, params):
return FunctionResource(fn=lambda: self.read(params), uri=uri) Defensive patterns
Strategy: type-guard
Validate before calling
import inspect assert inspect.iscoroutinefunction(MyTemplate.create_resource), "must implement create_resource()"
Type guard
def implements_create_resource(cls) -> bool:
return getattr(cls.create_resource, "__qualname__", "") != "ResourceTemplate.create_resource" Try / catch
try:
resource = await template.create_resource(uri, params)
except NotImplementedError:
resource = FunctionResourceTemplate(fn, uri_template=template.uri_template) Prevention
- Subclass FunctionResourceTemplate when task-capable resource creation is needed
- Implement create_resource() returning a concrete Resource for custom templates
- Keep custom templates out of code paths that require create_resource unless implemented
When it happens
Trigger: Custom ResourceTemplate subclass where _read reaches create_resource() without an override; using a bare ResourceTemplate subclass in a context requiring task-capable resource creation.
Common situations: Authors of custom templates who only implemented read() but the caller path (task-enabled reads) invokes create_resource; forgetting the docstring's guidance to use FunctionResourceTemplate.
Related errors
- Subclasses must implement read() or override create_resource
- Subclasses must implement render()
- Subclasses must implement read()
- Invalid boolean value for {param_name}: {param_value!r}
- Subclasses must implement verify_token
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/cd8622339454e641.
Report an issue: GitHub.