chroma-core/chroma · error · ValueError
Failed to convert image numpy array to base64 data URI: {e}
Error message
Failed to convert image numpy array to base64 data URI: {e} What it means
Each image ndarray goes through PIL.Image.fromarray(...), PNG save, and base64 encoding into a data:image/png;base64 URI; any exception in that chain is re-raised as this ValueError with the original error text appended after the colon. The usual culprit is an array PIL cannot interpret: float dtype (e.g. normalized 0..1 values), channel-first (3, H, W) shape, or an unsupported channel count.
Source
Thrown at chromadb/utils/embedding_functions/cohere_embedding_function.py:105
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(
f"Failed to convert image numpy array to base64 data URI: {e}"
) from e
return [
np.array(embeddings, dtype=np.float32)
for embeddings in self.client.embed(
images=base64_images,
model=self.model_name,
input_type="image",
).embeddings
]
else:
# Check if it's a mix or neither
has_texts = any(is_document(item) for item in input)
has_images = any(is_image(item) for item in input)
if has_texts and has_images:
raise ValueError(
"Input contains a mix of text documents and images, which is not supported. Provide either all texts or all images."View on GitHub (pinned to aecdd12c8a)
Solutions
- Read the {e} suffix - it carries PIL's original message ('Cannot handle this data type', 'not enough image data', etc.) and pinpoints the bad property.
- Convert to uint8 HWC: for CHW float input use arr = (np.clip(arr, 0, 1) * 255).astype(np.uint8).transpose(1, 2, 0).
- For cv2 images, convert BGR to RGB before embedding.
- In batch jobs, wrap per-image encoding in try/except to skip and log corrupt frames instead of failing the batch.
Example fix
# before arr = np.random.rand(3, 224, 224).astype(np.float32) # CHW, float ef([arr]) # ValueError: Failed to convert image numpy array to base64 data URI # after arr = np.transpose(arr, (1, 2, 0)) # HWC arr = (np.clip(arr, 0, 1) * 255).astype(np.uint8) ef([arr])
Defensive patterns
Strategy: try-catch
Validate before calling
import numpy as np
def pil_encodable(a: np.ndarray) -> bool:
return a.dtype == np.uint8 and a.ndim == 3 and a.shape[2] in (3, 4)
if not all(pil_encodable(x) for x in images):
images = [(np.clip(x, 0, 1) * 255).astype(np.uint8) if x.dtype != np.uint8 else x for x in images] Try / catch
for img in images:
try:
emb = ef([img])
except ValueError as e:
if 'base64 data URI' in str(e):
logger.warning('unencodable image skipped: %s', e) # PIL suffix says what is wrong
continue
raise Prevention
- Standardize on uint8 (H, W, 3|4) arrays before the EF sees them.
- Convert CHW/torch output with .transpose(1, 2, 0) and floats with (x * 255).astype(np.uint8).
- Read the PIL error suffix in the message - it names the exact property PIL rejected.
- In batch jobs, encode per-image with try/except to skip corrupt frames.
When it happens
Trigger: ef([np.random.rand(224, 224, 3)]) with float64 dtype; torchvision output transposed to (3, H, W); uint16/float32 arrays from scientific imaging; non-contiguous views that fromarray rejects.
Common situations: Feeding normalized tensors straight from a preprocessing pipeline; channel-first arrays from PyTorch models; cv2-loaded BGR or grayscale arrays without conversion/reshape.
Related errors
- The PIL python package is not installed. Please install it w
- Expected image input to be a numpy array, got {type(image_np
- Input contains a mix of text documents and images, which is
- Failed to convert image numpy array to base64 data URI: {e}
- Expected embeddings to be a list of floats or ints, a list o
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/17ffbe8eb427c284.
Report an issue: GitHub.