RyanCodrai/turbovec · error · ValueError

query_embedding dim does not match store dim

Error message

query_embedding dim {qvec.shape[1]} does not match store dim {expected_dim}

What it means

Raised in embedding_retrieval when the query vector's width differs from the store's committed dimension (self._index.dim). The query was embedded with a different model or configuration than the documents in the store, so similarity scoring would be meaningless.

Solutions

  1. Embed queries with the same embedder used to index the documents.
  2. Create/rebuild the store with the current embedder if the model intentionally changed.
  3. Catch the ValueError to surface embedder/store mismatch in retrieval pipelines instead of returning wrong results.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at turbovec-python/python/turbovec/haystack.py:625 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06). Data as JSON: /api/errors/91f7a26e637c3a83. Report an issue: GitHub.

Appendix: source

Thrown at turbovec-python/python/turbovec/haystack.py:625

        # Up-front validation, matching the reference: an empty or
        # non-numeric query embedding is a caller error regardless of
        # whether the store happens to be empty (issue #301). `Real`
        # rather than the reference's `isinstance(..., float)` so numpy
        # scalars and ints are accepted.
        if len(query_embedding) == 0 or not isinstance(query_embedding[0], Real):
            raise ValueError("query_embedding should be a non-empty list of floats.")

        if self.count_documents() == 0:
            return []

        qvec = np.asarray(query_embedding, dtype=np.float32)
        if qvec.ndim == 1:
            qvec = qvec[None, :]
        # By this point n_documents > 0, so the index has a committed dim.
        expected_dim = self._index.dim
        if qvec.shape[1] != expected_dim:
            raise ValueError(
                f"query_embedding dim {qvec.shape[1]} does not match store dim {expected_dim}"
            )
        # Cosine mode: normalize the query so the raw score against unit
        # document vectors is true cosine similarity.
        if self._vectors_normalized:
            qvec = l2_normalize_rows(qvec)
        if not qvec.flags["C_CONTIGUOUS"]:
            qvec = np.ascontiguousarray(qvec)

        if not filters:
            fetch_k = min(top_k, self.count_documents())
            scores, handles = self._index.search(qvec, fetch_k)
        else:
            self._validate_filters(filters)
            for _attempt in range(8):
                # Resolve filter → handle allowlist by walking the in-memory
                # doc table once. This is the same O(N) cost as the old
                # post-filter pass, just moved upfront so the kernel can

View on GitHub (pinned to ccab9f325e)