{"record":{"id":"978467813eda3da9","repo":"RyanCodrai/turbovec","slug":"embedding-dim-vectors-shape-1-does-not-match-st","errorCode":null,"errorMessage":"embedding dim {vectors.shape[1]} does not match store dim {existing_dim}","messagePattern":"embedding dim (.+?) does not match store dim (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"turbovec-python/python/turbovec/haystack.py","lineNumber":353,"sourceCode":"        )\n        if vectors.ndim != 2:\n            raise ValueError(\n                f\"expected 2D embedding batch, got {vectors.ndim}D\"\n            )\n        # A batch of empty per-document embeddings has shape (N, 0) — 2D,\n        # so it passes the ndim guard, then dies deep in the index kernel\n        # with an opaque buffer-length error. Name the real cause instead.\n        if vectors.shape[1] == 0:\n            raise ValueError(\n                \"documents have empty embeddings (dim 0); check the \"\n                \"embedder that produced them\"\n            )\n        # IdMapIndex.add_with_ids handles both eager (dim must match) and\n        # lazy (locks dim on first call) cases. Surface its mismatch\n        # panic as a clean ValueError for parity with previous behaviour.\n        existing_dim = self._index.dim\n        if existing_dim is not None and vectors.shape[1] != existing_dim:\n            raise ValueError(\n                f\"embedding dim {vectors.shape[1]} does not match store dim {existing_dim}\"\n            )\n        if not vectors.flags[\"C_CONTIGUOUS\"]:\n            vectors = np.ascontiguousarray(vectors)\n        # Cosine mode: L2-normalize so the kernel's raw score is true\n        # cosine similarity. Pure numpy on the just-built batch (no\n        # embedder call — Haystack documents arrive pre-embedded), so\n        # doing it alongside the rest of the batch prep under the\n        # caller's writer lock adds no blocking work. Zero rows pass\n        # through unchanged.\n        if self._vectors_normalized:\n            vectors = l2_normalize_rows(vectors)\n\n        handles = np.array(\n            [self._issue_handle() for _ in to_write], dtype=np.uint64\n        )\n\n        # Capture the previous handle of every overwritten id BEFORE the","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/RyanCodrai/turbovec/blob/ccab9f325e6ce2a270a87daf01ae4e443bcf2d49/turbovec-python/python/turbovec/haystack.py#L335-L371","documentation":"Raised in _commit_batch when the batch's embedding width differs from the store's committed dimension (self._index.dim, set at first write or from load). It converts what would be a Rust-side mismatch panic into a clean ValueError: documents were embedded with a different model/size than the store was built with.","triggerScenarios":"Thrown at turbovec-python/python/turbovec/haystack.py:353 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-embed documents with the same embedder used for the store's existing vectors.","Create a fresh store if the embedding model intentionally changed.","Catch the ValueError in ingestion pipelines to detect embedder/store configuration drift early."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ccab9f325e6ce2a270a87daf01ae4e443bcf2d49","analyzedAt":"2026-09-06T08:39:18.516Z","contentChangedAt":"2026-09-06T08:39:18.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}