{"record":{"id":"4bf132e1d6426f2b","repo":"BerriAI/litellm","slug":"unsupported-image-type-for-openrouter-image-edit","errorCode":null,"errorMessage":"Unsupported image type for OpenRouter image edit.","messagePattern":"Unsupported image type for OpenRouter image edit\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/openrouter/image_edit/transformation.py","lineNumber":367,"sourceCode":"        model_response._hidden_params[\"model\"] = response_json.get(\"model\", model)\n\n    def _read_image_bytes(self, image: FileTypes) -> bytes:\n        \"\"\"Read raw bytes from various image input types.\"\"\"\n        if isinstance(image, bytes):\n            return image\n        if isinstance(image, BytesIO):\n            current_pos = image.tell()\n            image.seek(0)\n            data = image.read()\n            image.seek(current_pos)\n            return data\n        if isinstance(image, BufferedReader):\n            current_pos = image.tell()\n            image.seek(0)\n            data = image.read()\n            image.seek(current_pos)\n            return data\n        raise ValueError(\"Unsupported image type for OpenRouter image edit.\")\n","sourceCodeStart":349,"sourceCodeEnd":368,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/openrouter/image_edit/transformation.py#L349-L368","documentation":"LiteLLM's OpenRouter image-edit handler reads the image argument via _read_image_bytes(), which accepts exactly three types: raw bytes, io.BytesIO, and io.BufferedReader (a file opened in binary mode). Any other object falls through to raise ValueError('Unsupported image type for OpenRouter image edit.') before any network call is made.","triggerScenarios":"Passing image as a filesystem path string, a bytearray, a PIL.Image.Image, a tempfile.SpooledTemporaryFile in text mode, or any custom file-like object to litellm.image_edit() with an openrouter/* model. Note plain bytes ARE accepted; only the listed stream/bytes types are.","commonSituations":"Switching from OpenAI's image_edit (which accepts paths or PIL objects in some wrappers) to an openrouter model; passing ImageFile received from a web framework; assuming bytearray behaves like bytes.","solutions":["Open file handles in binary mode: open(path, 'rb') returns the BufferedReader the handler accepts","Wrap in-memory data with io.BytesIO(data) (convert bytearray with bytes() first)","Convert PIL images by saving into an io.BytesIO buffer, e.g. img.save(buf, format='PNG')"],"exampleFix":"// before\nresp = litellm.image_edit(model=\"openrouter/google/gemini-2.5-flash-image-preview\", image=\"/tmp/cat.png\", prompt=\"add a hat\")\n\n// after\nimport io\nwith open(\"/tmp/cat.png\", \"rb\") as f:  # BufferedReader: accepted\n    resp = litellm.image_edit(model=\"openrouter/google/gemini-2.5-flash-image-preview\", image=f, prompt=\"add a hat\")\n# or for in-memory bytes (also accepted directly):\nresp = litellm.image_edit(model=\"openrouter/...\", image=io.BytesIO(png_bytes), prompt=\"add a hat\")","handlingStrategy":"validation","validationCode":"import io\n\ndef to_supported_image(image):\n    \"\"\"Adapt any common image input to a type OpenRouter image_edit accepts.\"\"\"\n    if isinstance(image, (bytes, io.BytesIO, io.BufferedReader)):\n        return image\n    if isinstance(image, bytearray):\n        return io.BytesIO(bytes(image))\n    if isinstance(image, str):\n        return open(image, \"rb\")\n    raise TypeError(f\"Cannot adapt {type(image).__name__} for OpenRouter image edit\")","typeGuard":"import io\nfrom typing import TypeGuard\n\ndef is_supported_image(image: object) -> TypeGuard[bytes | io.BytesIO | io.BufferedReader]:\n    return isinstance(image, (bytes, io.BytesIO, io.BufferedReader))","tryCatchPattern":"Optionally wrap the call in try/except ValueError and re-raise with a message that includes type(image).__name__ so the caller sees exactly which input type was rejected.","preventionTips":["Normalize all image arguments through one helper that returns bytes, io.BytesIO, or open(path,'rb')","Never pass PIL Image objects, path strings, or bytearray directly to openrouter image_edit","Add unit tests asserting your image inputs are one of the three supported types"],"tags":["openrouter","image-edit","input-validation","type-error","litellm"],"backgroundTag":"unsupported-argument-type","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}