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
When a Jina EF input item is an image (numpy array, per is_image), _build_payload converts it via PIL.Image.fromarray → PNG-encode → base64. Any exception in that chain (almost always PIL.Image.fromarray raising on a non-image array) is wrapped in ValueError('Failed to convert image numpy array to base64 data URI: {e}'). fromarray requires a 2-D or 3-D array of uint8 (or a small set of other dtypes) with a sane channel axis; anything else (1-D vectors, object dtype, bool, wrong C/W ordering) fails.
Source
Thrown at chromadb/utils/embedding_functions/jina_embedding_function.py:135
if all(is_document(item) for item in input):
payload["input"] = input
else:
for item in input:
if is_document(item):
payload["input"].append({"text": item})
elif is_image(item):
try:
pil_image = self._PILImage.fromarray(item)
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")
except Exception as e:
raise ValueError(
f"Failed to convert image numpy array to base64 data URI: {e}"
) from e
payload["input"].append({"image": base64_string})
if self.task is not None:
payload["task"] = self.task
if self.late_chunking is not None:
payload["late_chunking"] = self.late_chunking
if self.truncate is not None:
payload["truncate"] = self.truncate
if self.dimensions is not None:
payload["dimensions"] = self.dimensions
if self.embedding_type is not None:
payload["embedding_type"] = self.embedding_type
if self.normalized is not None:
payload["normalized"] = self.normalized
# overwrite parameteres when query payload is usedView on GitHub (pinned to aecdd12c8a)
Solutions
- Normalize arrays before ingestion: arr = np.asarray(arr); assert arr.dtype == np.uint8 and arr.ndim in (2, 3)
- Convert properly: PIL.Image.fromarray(np.uint8(arr)) or pass images opened via PIL and convert with np.asarray(img)
- Fix channel layout: cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) and ensure shape is (H, W, 3)
- For non-image numeric arrays, don't send them as documents — precompute and use add_embeddings instead
Example fix
# before
collection.add(documents=[np.ones((128,), dtype=np.float32)], ids=["1"]) # 1-D -> ValueError
# after
img = np.asarray(pil_or_cv2_image) # proper image source
if img.ndim == 2:
img = np.stack([img] * 3, axis=-1) # H,W -> H,W,3
img = np.ascontiguousarray(img, dtype=np.uint8)
collection.add(documents=[img], ids=["1"]) Defensive patterns
Strategy: try-catch
Validate before calling
import numpy as np
def to_image_array(arr: np.ndarray) -> np.ndarray:
arr = np.ascontiguousarray(arr)
if arr.ndim == 2:
arr = np.stack([arr] * 3, axis=-1)
if arr.dtype != np.uint8 or arr.ndim != 3 or arr.shape[2] not in (1, 3, 4):
raise ValueError(f"not a valid image array: dtype={arr.dtype}, shape={arr.shape}")
return arr
imgs = [to_image_array(a) for a in image_arrays]
collection.add(documents=imgs, ids=ids) Type guard
import numpy as np
def is_embeddable_image(x: object) -> bool:
"""True when PIL.Image.fromarray(x) will succeed for the Jina EF."""
return (
isinstance(x, np.ndarray)
and x.ndim in (2, 3)
and x.dtype == np.uint8
and (x.ndim == 2 or x.shape[-1] in (3, 4))
) Try / catch
try:
vectors = ef(image_arrays)
except ValueError as e:
if "Failed to convert image numpy array" in str(e):
bad = [i for i, a in enumerate(image_arrays) if not is_embeddable_image(a)]
raise ValueError(f"invalid image arrays at indices {bad}") from e
raise Prevention
- Canonicalize images once at load time: RGB, uint8, (H, W, 3), C-contiguous
- Never feed 1-D feature vectors as documents — embed them yourself and use add_embeddings
- Unit-test your ingestion transform with PIL.Image.fromarray to guarantee the EF's conversion will succeed
When it happens
Trigger: Passing a 1-D numpy array (e.g. a precomputed feature vector) as a document; an image array with dtype float64 or bool; an RGB array with a bogus shape like (3, H, W) or (H, W, 5); a zero-size array. Triggered on collection.add()/query() once payload building runs.
Common situations: Ingestion pipelines that feed raw numpy from cv2/PIL in unusual dtypes; documents mistakenly mixing embeddings (1-D floats) with images; images loaded with numpy.load from arbitrary .npy files.
Related errors
- The PIL python package is not installed. Please install it w
- Failed to convert image numpy array to base64 data URI: {e}
- SparseVector indices must be integers, got {type(idx).__name
- The PIL python package is not installed. Please install it w
- The PIL python package is not installed. Please install it w
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/e5ddcb747e7f611b.
Report an issue: GitHub.