deepset-ai/haystack · error · TypeError

MockDocumentEmbedder expects a list of Documents as input.In

Error message

MockDocumentEmbedder expects a list of Documents as input.In case you want to embed a string, please use the MockTextEmbedder.

What it means

MockDocumentEmbedder.run only accepts a list of haystack Document objects. If `documents` is not a list, or the first element is not a Document, it raises this TypeError and points you to MockTextEmbedder for embedding plain strings. It mirrors the type contract of the real OpenAIDocumentEmbedder so mocks are drop-in replacements.

Source

Thrown at haystack/components/embedders/mock_document_embedder.py:168

        if self.embedding is not None:
            return list(self.embedding)
        return _deterministic_embedding(text, self.dimension)

    @component.output_types(documents=list[Document], meta=dict[str, Any])
    def run(self, documents: list[Document]) -> dict[str, Any]:
        """
        Return the input documents with deterministic embeddings added, without calling any API.

        :param documents: A list of documents to embed.
        :returns: A dictionary with the following keys:
            - `documents`: A list of documents with embeddings.
            - `meta`: Metadata about the (mock) model.
        :raises TypeError: If `documents` is not a list of `Document` objects.
        """
        self.warm_up()

        if not isinstance(documents, list) or (documents and not isinstance(documents[0], Document)):
            raise TypeError(
                "MockDocumentEmbedder expects a list of Documents as input. "
                "In case you want to embed a string, please use the MockTextEmbedder."
            )

        texts_to_embed = [self._prepare_text_to_embed(document) for document in documents]
        new_documents = [
            replace(document, embedding=self._embed(text))
            for document, text in zip(documents, texts_to_embed, strict=True)
        ]

        meta: dict[str, Any] = {"model": self.model, "usage": _estimate_usage(texts_to_embed)}
        meta.update(self.meta)
        return {"documents": new_documents, "meta": meta}

    @component.output_types(documents=list[Document], meta=dict[str, Any])
    async def run_async(self, documents: list[Document]) -> dict[str, Any]:
        """
        Asynchronously return the input documents with deterministic embeddings added, without calling any API.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass `[Document(content="...")]` instead of a bare string or list of strings
  2. Use MockTextEmbedder if you actually want to embed a single string
  3. Check the upstream component in your pipeline — you may need a different embedder type

Example fix

// before
result = embedder.run("hello world")
// after
result = embedder.run([Document(content="hello world")])
Defensive patterns

Strategy: type-guard

Validate before calling

from haystack.dataclasses import Document
assert isinstance(documents, list) and (not documents or isinstance(documents[0], Document))
result = embedder.run(documents)

Type guard

def is_document_list(value) -> bool:
    from haystack.dataclasses import Document
    return isinstance(value, list) and (len(value) == 0 or isinstance(value[0], Document))

Try / catch

try:
    result = embedder.run(documents)
except TypeError:
    result = embedder.run([Document(content=str(documents))]) if isinstance(documents, str) else None

Prevention

When it happens

Trigger: `MockDocumentEmbedder().run("some text")` (a string instead of a list), `.run(["a", "b"])` (list of strings), or `.run([dict(content="x")])` (raw dicts not wrapped in Document).

Common situations: Wiring a TextEmbedder-shaped input into a DocumentEmbedder in a pipeline; forgetting to wrap strings with `Document(content=...)`; tests ported from a text embedder without adapting the input.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/f41d9c5a67d42150. Report an issue: GitHub.