{"record":{"id":"6fd7b2ad74b3dc1f","repo":"MemPalace/mempalace","slug":"sqlite-exact-collection-self-collection-name-r-6fd7b2","errorCode":null,"errorMessage":"sqlite_exact collection {self._collection_name!r} expects embedding dimension {stored}, got {dim}","messagePattern":"sqlite_exact collection (.+?) expects embedding dimension (.+?), got (.+?)","errorType":"validation","errorClass":"DimensionMismatchError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/sqlite_exact.py","lineNumber":351,"sourceCode":"\n    def _ensure_collection_dimension(self, cur, collection_id: int, dims: list[int]) -> None:\n        distinct = {int(dim) for dim in dims}\n        if not distinct:\n            return\n        if len(distinct) > 1:\n            raise DimensionMismatchError(\n                f\"sqlite_exact collection {self._collection_name!r} cannot mix \"\n                f\"embedding dimensions {sorted(distinct)}\"\n            )\n        dim = distinct.pop()\n        stored = self._collection_dimension(cur, collection_id)\n        if stored is None:\n            cur.execute(\n                \"UPDATE collections SET dimension = ? WHERE id = ?\",\n                (dim, collection_id),\n            )\n        elif stored != dim:\n            raise DimensionMismatchError(\n                f\"sqlite_exact collection {self._collection_name!r} expects \"\n                f\"embedding dimension {stored}, got {dim}\"\n            )\n\n    def _fts_available(self, cur) -> bool:\n        row = cur.execute(\"SELECT value FROM meta WHERE key = 'fts5_available'\").fetchone()\n        return bool(row and row[0] == \"1\")\n\n    def _embedder_meta_key(self) -> str:\n        return f\"embedder_model:{self._collection_name}\"\n\n    def get_stored_embedder_identity(self):\n        from .base import EmbedderIdentity\n\n        with self._cursor() as cur:\n            try:\n                cid = self._collection_id(cur)\n            except CollectionNotInitializedError:","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/sqlite_exact.py#L333-L369","documentation":"Raised by `_ensure_collection_dimension` during writes: every embedding in the batch has a consistent dimension, but it differs from the dimension already recorded in the `collections` table for this collection. The stored dimension is set once (first write) and then enforced, because a collection's vectors must be mutually comparable for cosine search.","triggerScenarios":"Writing to an existing collection with a new embedder of different size — e.g. collection built with 768-dim vectors, now upserting 1536-dim vectors; switching from one Ollama model to another and re-mining into the same palace.","commonSituations":"Upgrading the local embedding model and continuing incremental ingest into an existing palace; test fixtures that create collections with one embedder then run the suite with another; copying a palace built elsewhere with a different model config.","solutions":["If the model change is intentional, start a fresh collection/palace (or delete and recreate the collection) and re-ingest all content with the new model.","Otherwise, revert to the embedder whose dimension matches the stored one — check `get_stored_embedder_identity()` / the collection's dimension to find it.","Pin the embedding model in config so palace and pipeline cannot drift.","Never mix old cached vectors with a new model's vectors in the same collection."],"exampleFix":"# before\n# palace built with 768-dim model, now:\ncol.upsert(ids=ids, documents=docs, embeddings=[embed_mxbai(d) for d in docs])  # 1024-dim\n\n# after\nbackend.delete_collection(palace, \"drawers\")\ncol = backend.get_collection(palace, \"drawers\", create=True)\ncol.upsert(ids=all_ids, documents=all_docs, embeddings=[embed_mxbai(d) for d in all_docs])","handlingStrategy":"validation","validationCode":"def check_dims_match_collection(col, embeddings):\n    # decode expected dim from the collection\n    with col._cursor() as cur:\n        cid = col._collection_id(cur)\n        expected = col._collection_dimension(cur, cid)\n    if expected is not None and any(len(e) != expected for e in embeddings):\n        raise ValueError(f\"collection expects dim {expected}; re-embed or rebuild collection\")","typeGuard":null,"tryCatchPattern":"try:\n    col.upsert(ids=ids, documents=docs, embeddings=embs)\nexcept DimensionMismatchError as e:\n    logger.warning(\"dimension change detected (%s); rebuilding collection\", e)\n    backend.delete_collection(palace, name)\n    col = backend.get_collection(palace, name, create=True)\n    col.upsert(ids=all_ids, documents=all_docs, embeddings=[embed(d) for d in all_docs])","preventionTips":["Check get_stored_embedder_identity() before every ingest run and stop on mismatch.","Encode the embedding model name in the collection name or config when you intentionally change models.","Treat a model switch as a full rebuild, never an incremental append."],"tags":["sqlite-exact","embeddings","dimension-mismatch","model-switch"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}