{"record":{"id":"867c65b9a4908cc6","repo":"chroma-core/chroma","slug":"expected-image-input-to-be-a-numpy-array-got-typ","errorCode":null,"errorMessage":"Expected image input to be a numpy array, got {type(image_np)}","messagePattern":"Expected image input to be a numpy array, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/cohere_embedding_function.py","lineNumber":87,"sourceCode":"            Embeddings for the documents.\n        \"\"\"\n\n        # Cohere works with images. if all are texts, return the embeddings for the texts\n        if all(is_document(item) for item in input):\n            return [\n                np.array(embeddings, dtype=np.float32)\n                for embeddings in self.client.embed(\n                    texts=[str(item) for item in input],\n                    model=self.model_name,\n                    input_type=\"search_document\",\n                ).embeddings\n            ]\n\n        elif all(is_image(item) for item in input):\n            base64_images = []\n            for image_np in input:\n                if not isinstance(image_np, np.ndarray):\n                    raise ValueError(\n                        f\"Expected image input to be a numpy array, got {type(image_np)}\"\n                    )\n\n                try:\n                    pil_image = self._PILImage.fromarray(image_np)\n\n                    buffer = io.BytesIO()\n                    pil_image.save(buffer, format=\"PNG\")\n                    img_bytes = buffer.getvalue()\n\n                    # Encode bytes to base64 string\n                    base64_string = base64.b64encode(img_bytes).decode(\"utf-8\")\n\n                    data_uri = f\"data:image/png;base64,{base64_string}\"\n                    base64_images.append(data_uri)\n\n                except Exception as e:\n                    raise ValueError(","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/cohere_embedding_function.py#L69-L105","documentation":"When the input batch is classified as images, __call__ requires every item to be a numpy ndarray because each is passed directly to PIL.Image.fromarray for PNG/base64 encoding. Image-like objects that are not ndarrays - PIL Images, torch tensors, bytes, nested lists - fail this isinstance check before any encoding or API call happens.","triggerScenarios":"ef([PIL.Image.open('cat.png')]) or ef([torch_tensor]) inside the image branch; any images batch where at least one item fails isinstance(item, np.ndarray).","commonSituations":"Porting pipelines that hand PIL images or tensors around; preprocessing that keeps images as bytes; mixing representations in one batch.","solutions":["Convert every image to an ndarray first: np.asarray(pil_image) or tensor.numpy().","Ensure converted arrays are uint8 with (H, W, 3 or 4) shape so the next step (fromarray/.save) also succeeds.","If the items were meant to be text, pass str items instead so the text branch runs."],"exampleFix":"# before\nfrom PIL import Image\nef([Image.open('cat.png')])  # ValueError: expected numpy array\n\n# after\nimport numpy as np\nimg = np.asarray(Image.open('cat.png'))  # uint8 HWC ndarray\nef([img])","handlingStrategy":"type-guard","validationCode":"import numpy as np\nimages = [x if isinstance(x, np.ndarray) else np.asarray(x) for x in batch]","typeGuard":"import numpy as np\n\ndef is_ndarray_batch(batch: list) -> bool:\n    return len(batch) > 0 and all(isinstance(x, np.ndarray) for x in batch)","tryCatchPattern":"try:\n    embs = ef(batch)\nexcept ValueError as e:\n    if 'Expected image input to be a numpy array' in str(e):\n        batch = [np.asarray(x) for x in batch]  # convert PIL/tensor inputs, then retry\n        embs = ef(batch)\n    else:\n        raise","preventionTips":["Normalize image representations to uint8 ndarrays at the pipeline boundary.","Convert tensors with .numpy() and PIL with np.asarray before batching.","Keep one representation per batch; convert early, not at embed time."],"tags":["chroma","cohere","multimodal","numpy","input-validation"],"backgroundTag":"invalid-input-type","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}