{"record":{"id":"93b1b499c28327b6","repo":"unslothai/unsloth","slug":"image-original-name-is-too-large-width-x-hei","errorCode":null,"errorMessage":"Image '{original_name}' is too large ({width}x{height}); maximum is {_MAX_TRAINING_IMAGE_SIDE}px per side.","messagePattern":"Image '(.+?)' is too large \\((.+?)x(.+?)\\); maximum is (.+?)px per side\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/routes/training.py","lineNumber":3659,"sourceCode":"    arbitrary bytes under an image extension), so only oversized real images change behaviour.\"\"\"\n    from PIL import Image, UnidentifiedImageError\n\n    try:\n        with Image.open(path) as image:\n            width, height = image.size\n    except Image.DecompressionBombError:\n        # Past Pillow's ~179 MP limit Image.open() raises before .size can be read, with an error deriving straight from Exception, so letting it escape would 500 the upload.\n        raise HTTPException(\n            status_code = 400,\n            detail = (\n                f\"Image '{original_name}' is too large; maximum is \"\n                f\"{_MAX_TRAINING_IMAGE_SIDE}px per side.\"\n            ),\n        )\n    except (OSError, UnidentifiedImageError, ValueError):\n        return  # not a decodable image -> not a bomb; leave the existing contract\n    if width > _MAX_TRAINING_IMAGE_SIDE or height > _MAX_TRAINING_IMAGE_SIDE:\n        raise HTTPException(\n            status_code = 400,\n            detail = (\n                f\"Image '{original_name}' is too large ({width}x{height}); maximum is \"\n                f\"{_MAX_TRAINING_IMAGE_SIDE}px per side.\"\n            ),\n        )\n\n\ndef _safe_dataset_image_path(folder: Path, filename: str) -> Path:\n    \"\"\"Resolve ``filename`` to an image path strictly inside ``folder``. Rejects any path\n    separators / traversal / null bytes and non-image extensions.\"\"\"\n    raw = filename or \"\"\n    if \"/\" in raw or \"\\\\\" in raw or \"..\" in raw or \"\\x00\" in raw or raw != Path(raw).name:\n        raise HTTPException(status_code = 400, detail = \"Invalid image filename.\")\n    if Path(raw).suffix.lower() not in _DIFFUSION_DATASET_IMAGE_EXTS:\n        exts = \", \".join(sorted(_DIFFUSION_DATASET_IMAGE_EXTS))\n        raise HTTPException(status_code = 400, detail = f\"Not an image file. Allowed: {exts}\")\n    path = folder / raw","sourceCodeStart":3641,"sourceCodeEnd":3677,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/training.py#L3641-L3677","documentation":"HTTP 400 from _validate_uploaded_training_image: the image header was read successfully (no bomb error) and either width or height exceeds _MAX_TRAINING_IMAGE_SIDE (4096px, matching diffusion's limit). The specific measured dimensions are reported. Only the header is read, so the check is cheap; non-decodable bytes are intentionally passed through (the upload contract accepts arbitrary bytes under an image extension).","triggerScenarios":"Uploading a diffusion-dataset image whose real dimensions exceed 4096 on either side, e.g. a 6000x4000 photo exported at full resolution from a camera or a 8000px AI upscale.","commonSituations":"Raw camera exports (modern sensors exceed 4096 on the long edge); print-resolution scans; upscaled wallpapers; intermediate training outputs re-imported at full size.","solutions":["Downscale the image so both sides are <=4096px (e.g. magick convert in.png -resize '4096x4096>' out.png) and re-upload that file.","Batch-normalize whole folders: magick mogrify -resize '4096x4096>' *.png.","Configure your export/save pipeline (camera export, scanner, upscaler) to cap the long edge at 4096."],"exampleFix":"// before\nimg.save('train.png')  // 6000x4000 -> 400 on upload\n\n// after\nimg.thumbnail((4096, 4096))  # in-place, preserves aspect\nimg.save('train.png')","handlingStrategy":"validation","validationCode":"from PIL import Image\n\ndef within_side_limit(path: str, limit: int = 4096) -> bool:\n    with Image.open(path) as im:\n        w, h = im.size\n    return w <= limit and h <= limit","typeGuard":"def is_dimension_reject(exc: HTTPException) -> bool:\n    return exc.status_code == 400 and 'px per side' in exc.detail","tryCatchPattern":"try:\n    await upload(files=[f])\nexcept UploadRejected as e:  # wraps HTTPException detail\n    if 'px per side' in e.detail:\n        downscale_and_retry(f, 4096)\n    else:\n        raise","preventionTips":["Run mogrify/exports with a '4096x4096>' resize guard on every dataset pipeline.","Check dimensions of scraped data in your prep script; fail fast with the filename."],"tags":["image","pillow","http-400","validation","dataset"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}