{"record":{"id":"d6dadba6dbe2fa2e","repo":"PrefectHQ/fastmcp","slug":"only-one-of-path-or-data-can-be-provided","errorCode":null,"errorMessage":"Only one of path or data can be provided","messagePattern":"Only one of path or data can be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/utilities/types.py","lineNumber":256,"sourceCode":"        return types.MethodType(new_func, fn.__self__)\n    else:\n        return new_func\n\n\nclass Image:\n    \"\"\"Helper class for returning images from tools.\"\"\"\n\n    def __init__(\n        self,\n        path: str | Path | None = None,\n        data: bytes | None = None,\n        format: str | None = None,\n        annotations: Annotations | None = None,\n    ):\n        if path is None and data is None:\n            raise ValueError(\"Either path or data must be provided\")\n        if path is not None and data is not None:\n            raise ValueError(\"Only one of path or data can be provided\")\n\n        self.path = self._get_expanded_path(path)\n        self.data = data\n        self._format = format\n        self._mime_type = self._get_mime_type()\n        self.annotations = annotations\n\n    @staticmethod\n    def _get_expanded_path(path: str | Path | None) -> Path | None:\n        \"\"\"Expand environment variables and user home in path.\"\"\"\n        return Path(os.path.expandvars(str(path))).expanduser() if path else None\n\n    def _get_mime_type(self) -> str:\n        \"\"\"Get MIME type from format or guess from file extension.\"\"\"\n        if self._format:\n            return f\"image/{self._format.lower()}\"\n\n        if self.path:","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/utilities/types.py#L238-L274","documentation":"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__.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove one of the two arguments — keep data if you already have the bytes, otherwise keep path","If you want path-based loading, delete the manual file read and pass only path","In wrappers, forward only whichever source is not None"],"exampleFix":"// before\nImage(path='img.png', data=raw)\n// after\nImage(data=raw)  # or Image(path='img.png'), not both","handlingStrategy":"validation","validationCode":"def make_image(path=None, data=None):\n    if path is not None and data is not None:\n        data = None  # path wins; drop redundant bytes\n    return Image(path=path, data=data)","typeGuard":"def exactly_one(a, b) -> bool:\n    return (a is None) != (b is None)","tryCatchPattern":"try:\n    img = Image(path=path, data=data)\nexcept ValueError as e:\n    logger.warning(\"Ambiguous image source: %s\", e)\n    img = Image(path=path) if path else Image(data=data)","preventionTips":["Pick one source convention per call site (path OR bytes)","In helpers, forward only the non-None parameter","Don't pre-read files when passing path — let the library read lazily"],"tags":["validation","image","valueerror"],"backgroundTag":"invalid-parameter-value","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}