{"record":{"id":"5375c7a404c31849","repo":"docling-project/docling","slug":"unsupported-numpy-array-shape-img-shape-5375c7","errorCode":null,"errorMessage":"Unsupported numpy array shape: {img.shape}","messagePattern":"Unsupported numpy array shape: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/models/extraction/transformers_extraction_model.py","lineNumber":129,"sourceCode":"                    artifacts_path\n                )\n\n    def process_images(\n        self,\n        image_batch: Iterable[Union[Image, np.ndarray]],\n        prompt: Union[str, list[str]],\n    ) -> Iterable[VlmPrediction]:\n        from PIL import Image as PILImage\n\n        pil_images: list[Image] = []\n        for img in image_batch:\n            if isinstance(img, np.ndarray):\n                if img.ndim == 3 and img.shape[2] in (3, 4):\n                    pil_img = PILImage.fromarray(img.astype(np.uint8))\n                elif img.ndim == 2:\n                    pil_img = PILImage.fromarray(img.astype(np.uint8), mode=\"L\")\n                else:\n                    raise ValueError(f\"Unsupported numpy array shape: {img.shape}\")\n            else:\n                pil_img = img\n            if pil_img.mode != \"RGB\":\n                pil_img = pil_img.convert(\"RGB\")\n            pil_images.append(pil_img)\n\n        if not pil_images:\n            return\n\n        if isinstance(prompt, str):\n            templates = [prompt] * len(pil_images)\n        else:\n            if len(prompt) != len(pil_images):\n                raise ValueError(\n                    f\"Number of prompts ({len(prompt)}) must match \"\n                    f\"number of images ({len(pil_images)})\"\n                )\n            templates = prompt","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/models/extraction/transformers_extraction_model.py#L111-L147","documentation":"ValueError from image normalization in TransformersExtractionModel: numpy arrays passed in image_batch must be 2-D grayscale (H x W) or 3-D with 3 or 4 channels; any other shape (e.g. (H, W, 1) or channels-first (C, H, W)) cannot be converted to a PIL image and is rejected.","triggerScenarios":"Calling the extraction model with numpy image arrays whose ndim/shape[2] fall outside the accepted set; commonly grayscale arrays with a trailing singleton dimension or torch-style CHW arrays.","commonSituations":"Piping arrays from a preprocessing pipeline that normalizes to (H, W, 1); arrays converted from tensors with .numpy() keeping channels-first layout; mixed batches where some pages are (H, W) and others (H, W, 1).","solutions":["Normalize shapes upstream: img = img.reshape(img.shape[:2]) for (H, W, 1); img = img.transpose(1, 2, 0) for CHW.","Pass PIL Images or a uniform list of RGB numpy arrays (H, W, 3) to avoid the ambiguity.","Add an assert on shape before the call: img.ndim == 2 or (img.ndim == 3 and img.shape[2] in (3, 4))."],"exampleFix":"# before\nimage_batch = [chw_array]  # shape (3, H, W) -> ValueError\n\n# after\ndef to_hwc(img):\n    return img.transpose(1, 2, 0) if img.ndim == 3 and img.shape[0] in (3, 4) else img\nimage_batch = [to_hwc(img) for img in image_batch]","handlingStrategy":"validation","validationCode":"def to_pil_safe(img):\n    if isinstance(img, np.ndarray):\n        if img.ndim == 3 and img.shape[0] in (3, 4):\n            img = img.transpose(1, 2, 0)      # CHW -> HWC\n        if img.ndim == 3 and img.shape[2] == 1:\n            img = img[:, :, 0]               # drop singleton channel\n    return img\nimage_batch = [to_pil_safe(i) for i in image_batch]","typeGuard":"def is_convertible_array(img) -> bool:\n    return not isinstance(img, np.ndarray) or img.ndim == 2 or (img.ndim == 3 and img.shape[2] in (3, 4))","tryCatchPattern":"try:\n    preds = model(image_batch, prompt)\nexcept ValueError as e:\n    if 'Unsupported numpy array shape' in str(e):\n        image_batch = [to_pil_safe(i) for i in image_batch]\n        preds = model(image_batch, prompt)","preventionTips":["Standardize on HWC uint8 arrays (or PIL Images) at every boundary into extraction models.","Assert image shapes right after preprocessing, well before the model call."],"tags":["extraction","numpy","image-processing","transformers"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}