{"record":{"id":"6bbc635bd5fd50bf","repo":"opendatalab/MinerU","slug":"cannot-identify-image-file-img","errorCode":null,"errorMessage":"cannot identify image file {img}","messagePattern":"cannot identify image file (.+?)","errorType":"exception","errorClass":"LoadImageError","httpStatus":null,"severity":"error","filePath":"mineru/model/table/rec/unet_table/utils.py","lineNumber":101,"sourceCode":"        pass\n\n    def __call__(self, img: InputType) -> np.ndarray:\n        if not isinstance(img, InputType.__args__):\n            raise LoadImageError(\n                f\"The img type {type(img)} does not in {InputType.__args__}\"\n            )\n\n        img = self.load_img(img)\n        img = self.convert_img(img)\n        return img\n\n    def load_img(self, img: InputType) -> np.ndarray:\n        if isinstance(img, (str, Path)):\n            self.verify_exist(img)\n            try:\n                img = np.array(Image.open(img))\n            except UnidentifiedImageError as e:\n                raise LoadImageError(f\"cannot identify image file {img}\") from e\n            return img\n\n        if isinstance(img, bytes):\n            img = np.array(Image.open(BytesIO(img)))\n            return img\n\n        if isinstance(img, np.ndarray):\n            return img\n\n        raise LoadImageError(f\"{type(img)} is not supported!\")\n\n    def convert_img(self, img: np.ndarray):\n        if img.ndim == 2:\n            return cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)\n\n        if img.ndim == 3:\n            channel = img.shape[2]\n            if channel == 1:","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/table/rec/unet_table/utils.py#L83-L119","documentation":"When loading from a str/Path, PIL raises UnidentifiedImageError for files whose bytes are not a recognizable image format; the loader re-wraps it as LoadImageError('cannot identify image file <path>'). Corrupted, truncated, or non-image files hit this even though the path exists.","triggerScenarios":"Image.open() on a 0-byte file, a file with a wrong extension (e.g. WebP renamed .png with old Pillow lacking WebP support), a truncated download, or an HTML error page saved as an image.","commonSituations":"Interrupted downloads, disk-full partial writes, exotic formats (TIFF variants, JXL) not enabled in the installed Pillow build.","solutions":["Verify the file: file table.png and check size > 0.","Re-download or re-export the image.","Upgrade Pillow and install plugin extras (pip install -U 'pillow[plugins]' or pillow-heif etc.) for exotic formats.","Convert the image to PNG/JPEG with an external tool if the format is unsupported."],"exampleFix":"# before\nimg = load_image('page_3.png')  # actually HTML error page\n\n# after\n# validate magic first\nwith open(p,'rb') as f: head = f.read(8)\nif not head.startswith((b'\\\\x89PNG', b'\\\\xff\\\\xd8')):\n    raise ValueError(f'{p} is not a decodable image')\nimg = load_image(p)","handlingStrategy":"try-catch","validationCode":"def is_decodable_image(p) -> bool:\n    try:\n        with Image.open(p) as im:\n            im.verify()\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    img = load_image(path)\nexcept LoadImageError as e:\n    if 'cannot identify image file' in str(e):\n        logger.warning('bad image %s; skipping', path)\n        return None  # skip-and-continue for batch ingestion\n    raise","preventionTips":["Verify downloads with checksums before storing as images.","Check file size > 0 and magic bytes at ingest.","Keep Pillow and its codec plugins up to date."],"tags":["image-processing","file-corruption","pillow","table-recognition"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}