deepset-ai/haystack · error · TypeError

OpenAITextEmbedder expects a string as an input.In case you

Error message

OpenAITextEmbedder expects a string as an input.In case you want to embed a list of Documents, please use the OpenAIDocumentEmbedder.

What it means

OpenAITextEmbedder._prepare_input checks that `text` is a str before applying prefix/suffix and embedding. It raises TypeError for any non-string input because this component embeds exactly one string; lists of Documents belong in OpenAIDocumentEmbedder.

Source

Thrown at haystack/components/embedders/openai_text_embedder.py:199

            max_retries=self.max_retries,
            http_client_kwargs=self.http_client_kwargs,
        )

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "OpenAITextEmbedder":
        """
        Deserializes the component from a dictionary.

        :param data:
            Dictionary to deserialize from.
        :returns:
            Deserialized component.
        """
        return default_from_dict(cls, data)

    def _prepare_input(self, text: str) -> dict[str, Any]:
        if not isinstance(text, str):
            raise TypeError(
                "OpenAITextEmbedder expects a string as an input."
                "In case you want to embed a list of Documents, please use the OpenAIDocumentEmbedder."
            )

        text_to_embed = self.prefix + text + self.suffix

        kwargs: dict[str, Any] = {"model": self.model, "input": text_to_embed, "encoding_format": "float"}
        if self.dimensions is not None:
            kwargs["dimensions"] = self.dimensions
        return kwargs

    def _prepare_output(self, result: CreateEmbeddingResponse) -> dict[str, Any]:
        return {"embedding": result.data[0].embedding, "meta": {"model": result.model, "usage": dict(result.usage)}}

    @component.output_types(embedding=list[float], meta=dict[str, Any])
    def run(self, text: str) -> dict[str, Any]:
        """
        Embeds a single string.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass a plain string: `embedder.run(text="some text")`
  2. If embedding Documents, use OpenAITextEmbedder only per string, or switch to OpenAIDocumentEmbedder
  3. Add a converter (e.g. join strings or build Documents) upstream in the pipeline

Example fix

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

Strategy: type-guard

Validate before calling

if not isinstance(text, str):
    raise TypeError("OpenAITextEmbedder requires a str input")

Type guard

def is_str(value) -> bool:
    return isinstance(value, str)

Try / catch

try:
    result = embedder.run(text=text)
except TypeError as e:
    if "OpenAITextEmbedder expects a string" in str(e):
        result = doc_embedder.run(documents=text)  # if it is a Document list
    else:
        raise

Prevention

When it happens

Trigger: Calling `embedder.run(text=[Document(...)])`, `text=["a", "b"]`, or None — any non-str passed to run/run_async of OpenAITextEmbedder.

Common situations: Connecting a retriever/document list output to OpenAITextEmbedder by mistake; refactoring from DocumentEmbedder to TextEmbedder without changing input shape; passing pre-split chunks as a list.

Related errors


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