chroma-core/chroma · error · InvalidDimensionException
InvalidDimension
InvalidDimension
Error message
Embedding dimension {dim} does not match collection dimensionality {collection['dimension']} What it means
A Chroma collection is single-dimension: the first write sets collection['dimension'], and SegmentAPI._validate_dimension (reached via _validate_embedding_record_set on add/upsert) compares every subsequent embedding against it. On a mismatch it raises InvalidDimensionException (error code InvalidDimension) naming both the incoming dim and the collection's. You cannot mix embedding models of different sizes in one collection.
Source
Thrown at chromadb/api/segment.py:1153
if record["embedding"] is not None:
self._validate_dimension(
collection, len(record["embedding"]), update=True
)
# This method is intentionally left untraced because otherwise it can emit thousands of spans for requests containing many embeddings.
def _validate_dimension(
self, collection: t.Collection, dim: int, update: bool
) -> None:
"""Validate that a collection supports records of the given dimension. If update
is true, update the collection if the collection doesn't already have a
dimension."""
if collection["dimension"] is None:
if update:
id = collection.id
self._sysdb.update_collection(id=id, dimension=dim)
collection["dimension"] = dim
elif collection["dimension"] != dim:
raise InvalidDimensionException(
f"Embedding dimension {dim} does not match collection dimensionality {collection['dimension']}"
)
else:
return # all is well
@trace_method("SegmentAPI._get_collection", OpenTelemetryGranularity.ALL)
def _get_collection(self, collection_id: UUID) -> t.Collection:
collections = self._sysdb.get_collections(id=collection_id)
if not collections or len(collections) == 0:
raise NotFoundError(f"Collection {collection_id} does not exist.")
return collections[0]
@trace_method("SegmentAPI._scan", OpenTelemetryGranularity.OPERATION)
def _scan(self, collection_id: UUID) -> Scan:
collection_and_segments = self._sysdb.get_collection_with_segments(
collection_id
)
# For now collection should have exactly one segment per scope:View on GitHub (pinned to aecdd12c8a)
Solutions
- Recreate the collection after changing the embedding model: client.delete_collection(name) then get_or_create_collection with the new embedding_function
- Route every write through one embedding function so dimensions stay consistent
- Pre-check len(embedding) == collection.dimension (dimension is set after the first write) before add/upsert
Example fix
// before
coll.add(ids=['1'], embeddings=[[0.1] * 384]) # collection dim is 1536 -> InvalidDimensionException
// after
if getattr(coll, 'dimension', None) not in (None, 384):
client.delete_collection(coll.name)
coll = client.get_or_create_collection('docs', embedding_function=ef386)
coll.add(ids=['1'], embeddings=[[0.1] * 384]) Defensive patterns
Strategy: validation
Validate before calling
def check_dimensions(coll, embeddings) -> None:
dim = getattr(coll, 'dimension', None)
if dim is None:
return # first write sets the dimension
bad = [i for i, e in enumerate(embeddings) if len(e) != dim]
if bad:
raise ValueError(f'{len(bad)} embeddings have dimension != {dim} (e.g. index {bad[0]})')
check_dimensions(coll, embeddings)
coll.add(ids=ids, embeddings=embeddings) Type guard
def embeddings_match_dimension(coll, embeddings) -> bool:
dim = getattr(coll, 'dimension', None)
return dim is None or all(len(e) == dim for e in embeddings) Try / catch
from chromadb.errors import InvalidDimensionException
try:
coll.add(ids=ids, embeddings=embeddings)
except InvalidDimensionException:
raise RuntimeError(
f'collection {coll.name} has dimension {coll.dimension}; '
f'recreate it before switching embedding models') from None Prevention
- Pin one embedding function per collection; store the model name in collection metadata
- Recreate collections (delete + get_or_create) whenever the embedding model changes
- Add a startup assertion comparing your embedding function's output size to coll.dimension
When it happens
Trigger: coll.add(ids=..., embeddings=[[...]]) or upsert where the collection already has dimension N and the supplied vectors have a different length — e.g. 384-dim MiniLM vectors written into a 1536-dim OpenAI collection, or hand-built vectors of the wrong length.
Common situations: Switching embedding models (or the default embedding function) without recreating the collection; mixing default all-MiniLM-L6-v2 (384) with a custom embedding function; reusing an old persist directory with a new model; inconsistent vector lengths from buggy preprocessing.
Related errors
- Expected Embeddings to be non-empty list or numpy array, got
- embeddings and documents cannot both be undefined
- Expected embeddings to be a list of floats or ints, a list o
- At least one of one of {', '.join(record_set.keys())} must b
- Non-empty lists are required for {zero_lengths}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/43426194cb952ee7.
Report an issue: GitHub.