{"record":{"id":"73f59d4c1ddb63a0","repo":"PrefectHQ/fastmcp","slug":"either-path-or-data-must-be-provided","errorCode":null,"errorMessage":"Either path or data must be provided","messagePattern":"Either path or data must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/utilities/types.py","lineNumber":254,"sourceCode":"\n    if inspect.ismethod(fn):\n        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()}\"","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/utilities/types.py#L236-L272","documentation":"Image is a convenience wrapper around image bytes or a file path. Its constructor requires exactly one source: if both path and data are None there is nothing to encode, so it raises ValueError immediately. Construct it with either path= or data=, never neither.","triggerScenarios":"Image() with no arguments, Image(path=None, data=None), or passing the image source via a keyword the constructor does not accept (so both default to None).","commonSituations":"Dynamic code that builds an Image from optional user input where the variable is unset; refactors that renamed a variable but not the keyword; loading bytes conditionally and constructing Image unconditionally.","solutions":["Pass the file location: Image(path='img.png')","Pass raw bytes: Image(data=raw_bytes)","Guard the construction site so Image is only created when a source exists"],"exampleFix":"// before\nimg = Image()  # nothing provided\n// after\nimg = Image(path='chart.png')  # or Image(data=open('chart.png','rb').read())","handlingStrategy":"validation","validationCode":"def make_image(path=None, data=None):\n    if path is None and data is None:\n        raise ValueError(\"image source required: pass path or data\")\n    return Image(path=path, data=data)","typeGuard":"from typing import Optional\nfrom pathlib import Path\ndef has_image_source(path: Optional[str], data: Optional[bytes]) -> bool:\n    return path is not None or data is not None","tryCatchPattern":"try:\n    img = Image(path=path)\nexcept ValueError as e:\n    logger.error(\"Cannot build Image: %s\", e)\n    return None","preventionTips":["Only construct Image after the source variable is confirmed non-None","Use keyword arguments (Image(path=...)) to avoid positional/keyword mixups","Wrap construction in a factory that enforces exactly-one-source","Add type hints: path: str | None, data: bytes | None"],"tags":["validation","image","valueerror"],"backgroundTag":"missing-required-argument","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}