{"record":{"id":"0b926e0cf09720a6","repo":"MemPalace/mempalace","slug":"sqlite-exact-collection-self-collection-name-r-0b926e","errorCode":null,"errorMessage":"sqlite_exact collection {self._collection_name!r} expects embedding dimension {expected_dim}, got {int(q.size)}","messagePattern":"sqlite_exact collection (.+?) expects embedding dimension (.+?), got (.+?)","errorType":"exception","errorClass":"DimensionMismatchError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/sqlite_exact.py","lineNumber":612,"sourceCode":"            raise ValueError(\"query input must be a non-empty list\")\n\n        spec = _IncludeSpec.resolve(include, default_distances=True)\n        outer_ids: list[list[str]] = []\n        outer_docs: list[list[str]] = []\n        outer_metas: list[list[dict]] = []\n        outer_dists: list[list[float]] = []\n        outer_embeds: list[list[list[float]]] = []\n\n        with self._cursor() as cur:\n            collection_id = self._collection_id(cur)\n            expected_dim = self._collection_dimension(cur, collection_id)\n            rows = self._rows(cur, where=where, where_document=where_document)\n            row_vectors = [(row, _decode_array(row[\"embedding\"])) for row in rows]\n\n        for query_vector in query_embeddings:\n            q = _as_vector_array(query_vector)\n            if expected_dim is not None and int(q.size) != expected_dim:\n                raise DimensionMismatchError(\n                    f\"sqlite_exact collection {self._collection_name!r} expects \"\n                    f\"embedding dimension {expected_dim}, got {int(q.size)}\"\n                )\n            q_norm = float(np.linalg.norm(q))\n            scored = []\n            for row, vec in row_vectors:\n                if vec is None or vec.size != q.size:\n                    continue\n                denom = q_norm * float(np.linalg.norm(vec))\n                cos = 0.0 if denom <= 0 else float(np.dot(q, vec) / denom)\n                distance = 1.0 - max(-1.0, min(1.0, cos))\n                scored.append((distance, row, vec))\n            scored.sort(key=lambda item: item[0])\n            top = scored[:n_results]\n\n            outer_ids.append([row[\"id\"] for _, row, _ in top])\n            outer_docs.append([row[\"document\"] for _, row, _ in top] if spec.documents else [])\n            outer_metas.append([row[\"metadata\"] for _, row, _ in top] if spec.metadatas else [])","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/sqlite_exact.py#L594-L630","documentation":"Raised during query/search on a sqlite_exact collection: a query embedding's dimension does not match the dimension recorded for the collection. Unlike the write-side checks, this fires per query vector, after rows are loaded — the guard sits inside the query loop right before cosine scoring so the failure names the exact expected vs received sizes.","triggerScenarios":"Calling query/query_texts with embeddings from a different model than the one that built the collection — e.g. searching a 768-dim palace with 1536-dim query vectors; supplying `query_embeddings` manually computed with the wrong model; a changed default embedder in the searcher between ingest and search.","commonSituations":"Swapped the local embedding model after building the palace but before searching; a client computes embeddings with a different backend than the ingest pipeline; multiple palaces with different models and the wrong query path taken.","solutions":["Compute query embeddings with the same model used at ingest — check `col.get_stored_embedder_identity()` and match it.","If you must change models, rebuild/re-ingest the collection (see DimensionMismatchError on write) so both sides share one dimension.","Pre-validate before querying: `assert len(qvec) == expected_dim` where expected_dim comes from the collection metadata."],"exampleFix":"# before\n# collection built with 768-dim model\nresults = col.query(query_embeddings=[embed_large(\"query\")], n_results=5)  # 1536-dim\n\n# after\nresults = col.query(query_embeddings=[embed_small(\"query\")], n_results=5)  # 768-dim, same model as ingest","handlingStrategy":"validation","validationCode":"def validate_query_dim(col, query_embeddings):\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:\n        for q in query_embeddings:\n            if len(q) != expected:\n                raise ValueError(f\"query dim {len(q)} != collection dim {expected}; use the ingest embedder\")","typeGuard":null,"tryCatchPattern":"try:\n    col.query(query_embeddings=[qv], n_results=k)\nexcept DimensionMismatchError:\n    qv = embed_with_ingest_model(query_text)  # match stored identity\n    col.query(query_embeddings=[qv], n_results=k)","preventionTips":["Use the exact same embedder (model + version) for queries and ingest.","Store the embedder identity alongside search results during debugging.","Add an integration test that ingests then queries, so dimension drift breaks CI."],"tags":["sqlite-exact","query","embeddings","dimension-mismatch"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}