PrefectHQ/fastmcp · error · NotImplementedError

Subclasses must implement read()

Error message

Subclasses must implement read()

What it means

Resource.read() is an abstract-ish base method: the base Resource class cannot produce data on its own, so subclasses (FunctionResource, FileResource, etc.) must implement read(). Instantiating a custom Resource subclass without overriding read() leads to this NotImplementedError at read time (raised via _read).

Source

Thrown at fastmcp_slim/fastmcp/resources/base.py:423

        if self.name:
            pass
        elif self.uri:
            self.name = str(self.uri)
        else:
            raise ValueError("Either name or uri must be provided")
        return self

    async def read(
        self,
    ) -> str | bytes | ResourceResult:
        """Read the resource content.

        Subclasses implement this to return resource data. Supported return types:
            - str: Text content
            - bytes: Binary content
            - ResourceResult: Full control over contents and result-level meta
        """
        raise NotImplementedError("Subclasses must implement read()")

    def convert_result(self, raw_value: Any) -> ResourceResult:
        """Convert a raw result to ResourceResult.

        This is used in two contexts:
        1. In _read() to convert user function return values to ResourceResult
        2. In tasks_result_handler() to convert Docket task results to ResourceResult

        Handles ResourceResult passthrough and converts raw values using
        ResourceResult's normalization.  When the raw value is a plain
        string or bytes, the resource's own ``mime_type`` is forwarded so
        that ``ui://`` resources (and others with non-default MIME types)
        don't fall back to ``text/plain``.

        The resource's component-level ``meta`` (e.g. ``ui`` metadata for
        MCP Apps CSP/permissions) is propagated to each content item so
        that hosts can read it from the ``resources/read`` response.
        """

View on GitHub (pinned to 1f02114297)

Solutions

  1. Implement async def read(self) in your subclass returning str, bytes, or ResourceResult
  2. Or subclass/contribute via FunctionResource(fn) instead of extending Resource directly
  3. If you meant a template, implement ResourceTemplate.read()/create_resource() instead

Example fix

// before
class DbResource(Resource):
    pass  # read() missing
// after
class DbResource(Resource):
    async def read(self):
        return fetch_data()
Defensive patterns

Strategy: validation

Validate before calling

import inspect
assert inspect.iscoroutinefunction(MyResource.read), "subclass must implement async read()"

Type guard

def implements_read(cls) -> bool:
    return getattr(cls.read, "__qualname__", "") != "Resource.read"

Try / catch

try:
    content = await resource.read()
except NotImplementedError:
    logging.error(f"{type(resource).__name__} does not implement read()")
    raise

Prevention

When it happens

Trigger: class MyResource(Resource): pass then calling mcp.read_resource or MyResource().read(); a subclass overriding other hooks but not read().

Common situations: Custom resource subclasses where the author implemented __init__ or convert_result but forgot the async read() method; refactoring that renamed read accidentally.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/0b94799c6ec0c73a. Report an issue: GitHub.