RyanCodrai/turbovec · error · ValueError

Document {doc.id!r} has no embedding. TurboQuantDocumentStor

Error message

Document {doc.id!r} has no embedding. TurboQuantDocumentStore only stores documents with precomputed embeddings — run an embedder component before writing.

What it means

Raised in _write_documents_locked when a Document has embedding=None. TurboQuantDocumentStore stores only precomputed embeddings — there is no embedder inside the store — so writing an un-embedded document would create an unsearchable entry. It fires in both the FAIL path and the SKIP/OVERWRITE validation pass.

Source

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

            # stays persisted — a partial write. Mirror that observable
            # state exactly: validate and commit per document, raising on
            # the first collision. A repeated id within a single call
            # collides with its already-committed first instance, the same
            # way a cross-call repeat would. Each individual commit is
            # still all-or-nothing — validation precedes any mutation, so
            # a failing document mid-batch never leaves the index and the
            # id maps inconsistent (#89/#139 apply per document).
            written = 0
            for doc in documents:
                if doc.id in self._str_to_u64:
                    # Checked before embedding validation: the reference
                    # raises DuplicateDocumentError for a colliding id
                    # regardless of the document's other fields.
                    raise DuplicateDocumentError(
                        f"ID '{doc.id}' already exists in the document store."
                    )
                if doc.embedding is None:
                    raise ValueError(
                        f"Document {doc.id!r} has no embedding. "
                        "TurboQuantDocumentStore only stores documents with precomputed "
                        "embeddings — run an embedder component before writing."
                    )
                self._commit_batch([doc])
                written += 1
            return written

        # SKIP / OVERWRITE: first pass validates and resolves duplicates
        # against the batch-so-far as well as the existing store:
        # InMemoryDocumentStore writes into its dict as it iterates, so a
        # repeated id *within a single call* is resolved the same way a
        # cross-call repeat would be. Without tracking the batch, every
        # duplicate row still gets its own vector while _str_to_u64 keeps
        # only the last handle, orphaning the earlier vectors.
        to_write: List[Document] = []
        batch_pos: Dict[str, int] = {}  # doc.id -> index into to_write
        to_remove: List[str] = []  # existing ids to drop, deferred past add

View on GitHub (pinned to ccab9f325e)

Solutions

  1. Run a haystack Embedder component (e.g. SentenceTransformersDocumentEmbedder) on the documents before write_documents.
  2. Check the pipeline wiring: the embedder step may have been skipped or produced None for some documents.
  3. Catch the ValueError in ingestion code to identify which document ids lack embeddings.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at turbovec-python/python/turbovec/haystack.py:266 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/68f82fd6c96a4e2d. Report an issue: GitHub.