PrefectHQ/fastmcp · error · ValueError

No resource data available

Error message

No resource data available

What it means

`to_resource_content` builds a file:// URI for an EmbeddedResource. If the data object has no text content, no bytes (`data`), and no path, there is nothing to embed, so the method raises `ValueError("No resource data available")`. It is a guard against constructing an empty/malformed resource content block.

Source

Thrown at fastmcp_slim/fastmcp/utilities/types.py:436

        annotations: Annotations | None = None,
    ) -> mcp_types.EmbeddedResource:
        if self.path:
            with open(self.path, "rb") as f:
                raw_data = f.read()
                uri_str = self.path.resolve().as_uri()
        elif self.data is not None:
            raw_data = self.data
            if self._name:
                extension = (
                    ""
                    if Path(self._name).suffix
                    else f".{self._mime_type.split('/')[1]}"
                )
                uri_str = f"file:///{self._name}{extension}"
            else:
                uri_str = f"file:///resource.{self._mime_type.split('/')[1]}"
        else:
            raise ValueError("No resource data available")

        mime = mime_type or self._mime_type
        # Validate the URI shape, then pass the string form to the SDK types
        # (their `uri` fields are plain `str` in the v2 SDK).
        UriType = Annotated[AnyUrl, UrlConstraints(host_required=False)]
        uri = str(TypeAdapter(UriType).validate_python(uri_str))

        if mime.startswith("text/"):
            try:
                text = raw_data.decode("utf-8")
            except UnicodeDecodeError:
                text = raw_data.decode("latin-1")
            resource = mcp_types.TextResourceContents(
                text=text,
                mime_type=mime,
                uri=uri,
            )
        else:

View on GitHub (pinned to 1f02114297)

Solutions

  1. Populate the resource with content before converting: pass `data=...` bytes, `text=...`, or a valid `path`.
  2. Check the payload is non-empty before calling `to_resource_content` (e.g. skip None/empty reads upstream).
  3. If a placeholder URI is acceptable, supply mime_type with data so the fallback `file:///resource.<sub>` branch is used instead.
  4. Wrap the call in try/except ValueError to handle legitimately empty resources.

Example fix

// before
rc = EmbeddedResource(name="out.txt", mime_type="text/plain")
block = rc.to_resource_content()  # ValueError
// after
rc = EmbeddedResource(name="out.txt", mime_type="text/plain", text="hello")
block = rc.to_resource_content()
Defensive patterns

Strategy: validation

Validate before calling

def can_convert(rc) -> bool:
    return bool(getattr(rc, "text", None)) or getattr(rc, "data", None) is not None or getattr(rc, "path", None) is not None
# skip: if not can_convert(rc): continue

Type guard

from typing import Any
def has_payload(rc: Any) -> bool:
    return bool(getattr(rc, "text", None)) or getattr(rc, "data", None) is not None or getattr(rc, "path", None) is not None

Try / catch

try:
    block = rc.to_resource_content()
except ValueError as e:
    if "No resource data available" not in str(e):
        raise
    block = None  # or skip/log

Prevention

When it happens

Trigger: Calling `to_resource_content()` on a `ResourceContent`-like object where text is empty/None, `data` is None, and `path` is None — e.g. a resource created without any payload or with a failed data load.

Common situations: Fetching a resource whose read returned nothing; constructing the types helper manually with only a name/mime_type and forgetting the payload; tests exercising the empty-data branch.

Related errors


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