{"record":{"id":"35400da3962dfcb9","repo":"unslothai/unsloth","slug":"could-not-decode-image-exc","errorCode":null,"errorMessage":"Could not decode image: {exc}","messagePattern":"Could not decode image: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/diffusion.py","lineNumber":388,"sourceCode":"        # data:[<mime>][;base64],<payload>\n        _, _, raw = raw.partition(\",\")\n    try:\n        blob = base64.b64decode(raw, validate = False)\n    except (binascii.Error, ValueError) as exc:\n        raise ValueError(f\"Invalid base64 image data: {exc}\") from exc\n    # Bound the decoded size: 4096px covers txt2img 2048, upscales and outpaint canvases.\n    max_side = 4096\n    try:\n        img = Image.open(io.BytesIO(blob))\n        # Reject from the header before img.load() so a huge-dimension file cannot spike memory.\n        w, h = img.size\n        if w > max_side or h > max_side:\n            raise ValueError(f\"Image is too large ({w}x{h}); maximum is {max_side}px per side.\")\n        img.load()\n    except ValueError:\n        raise  # the size guard's own message; don't wrap it as a decode error\n    except Exception as exc:  # noqa: BLE001 — surfaced as a 400 to the client\n        raise ValueError(f\"Could not decode image: {exc}\") from exc\n    return img.convert(mode)\n\n\ndef _snap_to_multiple(img: Any, multiple: int = 16) -> Any:\n    \"\"\"Resize a PIL image so both sides are multiples of ``multiple`` (rounded to nearest,\n    minimum one multiple), preserving content with a high-quality resample.\n\n    Image-conditioned pipelines (Z-Image / Qwen / FLUX: 8x VAE downsample + 2x patch) reject\n    sizes that are not divisible by 16. Rather than error on an odd-sized upload, snap it so\n    the workflow just works; rounding to nearest keeps the rescale minimal/accurate.\"\"\"\n    from PIL import Image\n\n    w, h = img.size\n    nw = max(multiple, int(round(w / multiple)) * multiple)\n    nh = max(multiple, int(round(h / multiple)) * multiple)\n    if (nw, nh) != (w, h):\n        img = img.resize((nw, nh), Image.LANCZOS)\n    return img","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/diffusion.py#L370-L406","documentation":"Raised when PIL fails to open or fully load the decoded blob — Image.open/size/load raised something other than the size ValueError (which is re-raised untouched). The bytes were valid base64 but not a decodable image: wrong format, corrupt file, truncated upload, or an unsupported codec.","triggerScenarios":"Base64 of a PDF, WebP variant PIL cannot handle, or truncated multi-part file; HEIC/AVIF without decoder support in the installed Pillow; an image with a corrupt trailer failing at img.load().","commonSituations":"iPhone HEIC photos passed through untouched; files renamed to .png without conversion; partial uploads; Pillow built without libwebp.","solutions":["Convert the image to PNG or JPEG with a local tool before sending — these always decode","For HEIC/AVIF/WebP sources, install Pillow with the needed codecs (pillow-heif, libwebp) on the producing side, or convert there","Verify the file opens locally in an image viewer before uploading"],"exampleFix":"# before: sending HEIC bytes base64-encoded\n\n# after: convert first\nfrom PIL import Image\nimg = Image.open(\"photo.heic\").convert(\"RGB\")\nimg.save(\"photo.jpg\")","handlingStrategy":"try-catch","validationCode":"def decodable_image(data: str) -> bool:\n    import base64, io\n    from PIL import Image\n    raw = data.strip().partition(\",\")[2] if data.strip().startswith(\"data:\") else data.strip()\n    try:\n        with Image.open(io.BytesIO(base64.b64decode(raw))) as im:\n            im.size\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    img = parse_b64_image(data)\nexcept ValueError as e:\n    if \"Could not decode image\" in str(e):\n        ask_user_to_reupload_as(\"PNG or JPEG\")","preventionTips":["Convert HEIC/AVIF/exotic formats to PNG or JPEG before upload","Ensure Pillow is built with libwebp if WebP inputs are expected","Verify files open in a viewer before sending"],"tags":["diffusion","image","pillow","decode","client-error"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}