{"record":{"id":"43426194cb952ee7","repo":"chroma-core/chroma","slug":"invaliddimension","errorCode":"InvalidDimension","errorMessage":"Embedding dimension {dim} does not match collection dimensionality {collection['dimension']}","messagePattern":"Embedding dimension (.+?) does not match collection dimensionality (.+?)","errorType":"exception","errorClass":"InvalidDimensionException","httpStatus":400,"severity":"error","filePath":"chromadb/api/segment.py","lineNumber":1153,"sourceCode":"            if record[\"embedding\"] is not None:\n                self._validate_dimension(\n                    collection, len(record[\"embedding\"]), update=True\n                )\n\n    # This method is intentionally left untraced because otherwise it can emit thousands of spans for requests containing many embeddings.\n    def _validate_dimension(\n        self, collection: t.Collection, dim: int, update: bool\n    ) -> None:\n        \"\"\"Validate that a collection supports records of the given dimension. If update\n        is true, update the collection if the collection doesn't already have a\n        dimension.\"\"\"\n        if collection[\"dimension\"] is None:\n            if update:\n                id = collection.id\n                self._sysdb.update_collection(id=id, dimension=dim)\n                collection[\"dimension\"] = dim\n        elif collection[\"dimension\"] != dim:\n            raise InvalidDimensionException(\n                f\"Embedding dimension {dim} does not match collection dimensionality {collection['dimension']}\"\n            )\n        else:\n            return  # all is well\n\n    @trace_method(\"SegmentAPI._get_collection\", OpenTelemetryGranularity.ALL)\n    def _get_collection(self, collection_id: UUID) -> t.Collection:\n        collections = self._sysdb.get_collections(id=collection_id)\n        if not collections or len(collections) == 0:\n            raise NotFoundError(f\"Collection {collection_id} does not exist.\")\n        return collections[0]\n\n    @trace_method(\"SegmentAPI._scan\", OpenTelemetryGranularity.OPERATION)\n    def _scan(self, collection_id: UUID) -> Scan:\n        collection_and_segments = self._sysdb.get_collection_with_segments(\n            collection_id\n        )\n        # For now collection should have exactly one segment per scope:","sourceCodeStart":1135,"sourceCodeEnd":1171,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/segment.py#L1135-L1171","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ncoll.add(ids=['1'], embeddings=[[0.1] * 384])  # collection dim is 1536 -> InvalidDimensionException\n\n// after\nif getattr(coll, 'dimension', None) not in (None, 384):\n    client.delete_collection(coll.name)\n    coll = client.get_or_create_collection('docs', embedding_function=ef386)\ncoll.add(ids=['1'], embeddings=[[0.1] * 384])","handlingStrategy":"validation","validationCode":"def check_dimensions(coll, embeddings) -> None:\n    dim = getattr(coll, 'dimension', None)\n    if dim is None:\n        return  # first write sets the dimension\n    bad = [i for i, e in enumerate(embeddings) if len(e) != dim]\n    if bad:\n        raise ValueError(f'{len(bad)} embeddings have dimension != {dim} (e.g. index {bad[0]})')\n\ncheck_dimensions(coll, embeddings)\ncoll.add(ids=ids, embeddings=embeddings)","typeGuard":"def embeddings_match_dimension(coll, embeddings) -> bool:\n    dim = getattr(coll, 'dimension', None)\n    return dim is None or all(len(e) == dim for e in embeddings)","tryCatchPattern":"from chromadb.errors import InvalidDimensionException\n\ntry:\n    coll.add(ids=ids, embeddings=embeddings)\nexcept InvalidDimensionException:\n    raise RuntimeError(\n        f'collection {coll.name} has dimension {coll.dimension}; '\n        f'recreate it before switching embedding models') from None","preventionTips":["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"],"tags":["chroma","embeddings","dimension-mismatch","invalid-dimension","add"],"backgroundTag":"embedding-dimension-mismatch","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}