RyanCodrai/turbovec · error · ValueError

expected 2D embedding batch, got {vectors.ndim}D

Error message

expected 2D embedding batch, got {vectors.ndim}D

What it means

Raised in _store_texts_and_vectors when the vector batch is not a 2D (N, dim) matrix — the input to add_texts collapsed to 0D (empty) or 1D/3D (wrong rank). This is the last-line shape guard for embedder outputs that passed the earlier row-count/dim-0 checks.

Source

Thrown at turbovec-python/python/turbovec/langchain.py:365

        # See add_documents: materialize one-shot iterables once.
        documents = list(documents)
        texts = [doc.page_content for doc in documents]
        metadatas = [doc.metadata for doc in documents]
        if ids is None:
            ids = [doc.id or str(uuid.uuid4()) for doc in documents]
        return await self.aadd_texts(
            texts=texts, metadatas=metadatas, ids=ids, **kwargs
        )

    def _store_texts_and_vectors(
        self,
        texts_list: list[str],
        vectors: np.ndarray,
        metadatas: list[dict],
        ids: list[str],
    ) -> list[str]:
        if vectors.ndim != 2:
            raise ValueError(f"expected 2D embedding batch, got {vectors.ndim}D")

        # Validate every metadata entry before touching any state. A bad
        # entry (e.g. None) previously blew up as `dict(None)` mid-loop,
        # *after* the vectors had been added to the index — leaving the
        # docstore and index desynced in memory (and dump() would persist
        # the corruption). The reference InMemoryVectorStore rejects bad
        # metadata with a named error; mirror that here.
        for i, meta in enumerate(metadatas):
            if not isinstance(meta, dict):
                raise TypeError(
                    f"metadatas[{i}] must be a dict, "
                    f"got {type(meta).__name__}"
                )

        # Dedup intra-batch duplicate ids, keeping the last occurrence —
        # matches InMemoryVectorStore, whose dict store silently overwrites
        # on a repeated id. Without this every row is added to the index but
        # _str_to_u64 keeps only the last handle per id, orphaning the

View on GitHub (pinned to ccab9f325e)

Solutions

  1. Ensure the embedder returns one flat vector per text so np.asarray yields a 2D float32 matrix.
  2. Check for empty input batches or nested/ragged embedding lists.
  3. Catch the ValueError to abort before any metadata validation or index mutation.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at turbovec-python/python/turbovec/langchain.py:365 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/6231199064169925. Report an issue: GitHub.