{"record":{"id":"2f1e96c5a5d67694","repo":"BerriAI/litellm","slug":"nova-canvas-image-edit-does-not-support-tuple-file","errorCode":null,"errorMessage":"Nova Canvas image edit does not support tuple FileTypes. Pass a file-like object, bytes, or a base64-encoded string.","messagePattern":"Nova Canvas image edit does not support tuple FileTypes\\. Pass a file-like object, bytes, or a base64-encoded string\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/bedrock/image_edit/amazon_nova_canvas_image_edit_transformation.py","lineNumber":148,"sourceCode":"\ndef _file_types_to_b64(image: FileTypes | None) -> str:\n    \"\"\"Encode OpenAI image input to base64 string for Nova Canvas.\"\"\"\n    if image is None:\n        raise ValueError(\"Nova Canvas image edit requires an image input\")\n    if hasattr(image, \"read\") and callable(getattr(image, \"read\", None)):\n        if hasattr(image, \"seek\"):\n            image.seek(0)\n        image_bytes: Final = image.read()\n        return base64.b64encode(image_bytes).decode(\"utf-8\")\n    if isinstance(image, bytes):\n        return base64.b64encode(image).decode(\"utf-8\")\n    if isinstance(image, str):\n        return image\n    if isinstance(image, os.PathLike):\n        with open(image, \"rb\") as f:\n            return base64.b64encode(f.read()).decode(\"utf-8\")\n    if isinstance(image, tuple):\n        raise ValueError(\n            \"Nova Canvas image edit does not support tuple FileTypes. \"\n            \"Pass a file-like object, bytes, or a base64-encoded string.\"\n        )\n    return base64.b64encode(bytes(image)).decode(\"utf-8\")\n\n\ndef _supports_nova_canvas_image_edit_from_model_cost(model: str) -> bool:\n    \"\"\"\n    True when model_cost has supports_nova_canvas_image_edit for a resolved catalog key.\n\n    get_model_info / ModelInfoBase omit arbitrary JSON keys, so we read model_cost\n    directly (same idea as supports_* bare_entry fallback).\n    \"\"\"\n    import litellm as _litellm\n\n    if not model:\n        return False\n","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/bedrock/image_edit/amazon_nova_canvas_image_edit_transformation.py#L130-L166","documentation":"The FileTypes union used by OpenAI-style image APIs includes multipart tuple forms like (filename, bytes, content_type). Nova Canvas image edit sends JSON with base64 fields to Bedrock InvokeModel, not multipart, and its encoder only accepts file-like objects, bytes, base64 strings, and os.PathLike — tuples are rejected explicitly.","triggerScenarios":"image=('/tmp/cat.png', png_bytes, 'image/png') (or the same shape for mask=) — typically produced by helpers that build multipart file tuples for form uploads.","commonSituations":"Reusing OpenAI SDK / FastAPI / requests multipart file-building code; storing uploads as (name, bytes, mime) tuples and forwarding them to image_edit.","solutions":["Pass the raw bytes: image=png_bytes","Pass a file object (open('cat.png', 'rb')), a base64-encoded string, or a pathlib.Path","Unpack tuples before the call: image = tup[1] if isinstance(tup, tuple) else tup"],"exampleFix":"# before\nimg = (\"cat.png\", png_bytes, \"image/png\")\nresp = litellm.image_edit(model=\"bedrock/amazon.nova-canvas-v1:0\", image=img, prompt=\"...\")\n\n# after\nresp = litellm.image_edit(model=\"bedrock/amazon.nova-canvas-v1:0\", image=png_bytes, prompt=\"...\")","handlingStrategy":"type-guard","validationCode":"def normalize_file_types(value):\n    \"\"\"Convert multipart tuples to bytes for Nova Canvas edit calls.\"\"\"\n    if isinstance(value, tuple):\n        for part in value:\n            if isinstance(part, (bytes, bytearray)):\n                return bytes(part)\n        raise ValueError(\"tuple FileTypes must contain bytes\")\n    return value\n\nimage = normalize_file_types(raw_upload)","typeGuard":"def is_nova_canvas_file_types(value) -> bool:\n    \"\"\"True when value is accepted by Nova Canvas: file-like, bytes, base64 str, PathLike.\"\"\"\n    if value is None:\n        return False\n    if isinstance(value, tuple):\n        return False\n    return (\n        callable(getattr(value, \"read\", None))\n        or isinstance(value, (bytes, bytearray, str))\n        or isinstance(value, os.PathLike)\n    )","tryCatchPattern":"try:\n    resp = litellm.image_edit(...)\nexcept ValueError as e:\n    if \"does not support tuple FileTypes\" in str(e):\n        resp = litellm.image_edit(..., image=image_tuple[1])  # bytes element\n    else:\n        raise","preventionTips":["Standardize on bytes for in-memory images crossing API boundaries","Adapt multipart tuples from web frameworks to raw bytes at the edge","Unit-test your upload normalization with every FileTypes shape you accept"],"tags":["bedrock","nova-canvas","image-edit","filetypes","input-type","multipart"],"backgroundTag":"unsupported-input-type","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}