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

  1. Recreate the collection after changing the embedding model: client.delete_collection(name) then get_or_create_collection with the new embedding_function
  2. Route every write through one embedding function so dimensions stay consistent
  3. 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

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


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