PrefectHQ/fastmcp · error · ValueError

Only one of path or data can be provided

Error message

Only one of path or data can be provided

What it means

Image accepts exactly one of path or data. Supplying both is ambiguous (the library cannot know which is authoritative), so the constructor raises ValueError. This is the counterpart to the 'neither provided' check at the top of the same __init__.

Source

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

        return types.MethodType(new_func, fn.__self__)
    else:
        return new_func


class Image:
    """Helper class for returning images from tools."""

    def __init__(
        self,
        path: str | Path | None = None,
        data: bytes | None = None,
        format: str | None = None,
        annotations: Annotations | None = None,
    ):
        if path is None and data is None:
            raise ValueError("Either path or data must be provided")
        if path is not None and data is not None:
            raise ValueError("Only one of path or data can be provided")

        self.path = self._get_expanded_path(path)
        self.data = data
        self._format = format
        self._mime_type = self._get_mime_type()
        self.annotations = annotations

    @staticmethod
    def _get_expanded_path(path: str | Path | None) -> Path | None:
        """Expand environment variables and user home in path."""
        return Path(os.path.expandvars(str(path))).expanduser() if path else None

    def _get_mime_type(self) -> str:
        """Get MIME type from format or guess from file extension."""
        if self._format:
            return f"image/{self._format.lower()}"

        if self.path:

View on GitHub (pinned to 1f02114297)

Solutions

  1. Remove one of the two arguments — keep data if you already have the bytes, otherwise keep path
  2. If you want path-based loading, delete the manual file read and pass only path
  3. In wrappers, forward only whichever source is not None

Example fix

// before
Image(path='img.png', data=raw)
// after
Image(data=raw)  # or Image(path='img.png'), not both
Defensive patterns

Strategy: validation

Validate before calling

def make_image(path=None, data=None):
    if path is not None and data is not None:
        data = None  # path wins; drop redundant bytes
    return Image(path=path, data=data)

Type guard

def exactly_one(a, b) -> bool:
    return (a is None) != (b is None)

Try / catch

try:
    img = Image(path=path, data=data)
except ValueError as e:
    logger.warning("Ambiguous image source: %s", e)
    img = Image(path=path) if path else Image(data=data)

Prevention

When it happens

Trigger: Image(path='img.png', data=b'...') — both sources given, often when a caller reads the file into bytes but also passes the path for convenience.

Common situations: Helper functions that forward both path and preloaded bytes; migrating code from a data-only call to path-based and leaving the old argument in place.

Related errors


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