chroma-core/chroma · error · ValueError

Expected image input to be a numpy array, got {type(image_np

Error message

Expected image input to be a numpy array, got {type(image_np)}

What it means

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.

Source

Thrown at chromadb/utils/embedding_functions/cohere_embedding_function.py:87

            Embeddings for the documents.
        """

        # Cohere works with images. if all are texts, return the embeddings for the texts
        if all(is_document(item) for item in input):
            return [
                np.array(embeddings, dtype=np.float32)
                for embeddings in self.client.embed(
                    texts=[str(item) for item in input],
                    model=self.model_name,
                    input_type="search_document",
                ).embeddings
            ]

        elif all(is_image(item) for item in input):
            base64_images = []
            for image_np in input:
                if not isinstance(image_np, np.ndarray):
                    raise ValueError(
                        f"Expected image input to be a numpy array, got {type(image_np)}"
                    )

                try:
                    pil_image = self._PILImage.fromarray(image_np)

                    buffer = io.BytesIO()
                    pil_image.save(buffer, format="PNG")
                    img_bytes = buffer.getvalue()

                    # Encode bytes to base64 string
                    base64_string = base64.b64encode(img_bytes).decode("utf-8")

                    data_uri = f"data:image/png;base64,{base64_string}"
                    base64_images.append(data_uri)

                except Exception as e:
                    raise ValueError(

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Convert every image to an ndarray first: np.asarray(pil_image) or tensor.numpy().
  2. Ensure converted arrays are uint8 with (H, W, 3 or 4) shape so the next step (fromarray/.save) also succeeds.
  3. If the items were meant to be text, pass str items instead so the text branch runs.

Example fix

# before
from PIL import Image
ef([Image.open('cat.png')])  # ValueError: expected numpy array

# after
import numpy as np
img = np.asarray(Image.open('cat.png'))  # uint8 HWC ndarray
ef([img])
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np
images = [x if isinstance(x, np.ndarray) else np.asarray(x) for x in batch]

Type guard

import numpy as np

def is_ndarray_batch(batch: list) -> bool:
    return len(batch) > 0 and all(isinstance(x, np.ndarray) for x in batch)

Try / catch

try:
    embs = ef(batch)
except ValueError as e:
    if 'Expected image input to be a numpy array' in str(e):
        batch = [np.asarray(x) for x in batch]  # convert PIL/tensor inputs, then retry
        embs = ef(batch)
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: Porting pipelines that hand PIL images or tensors around; preprocessing that keeps images as bytes; mixing representations in one batch.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/867c65b9a4908cc6. Report an issue: GitHub.