deepset-ai/haystack · error · TypeError

{name} must be a sequence of numbers, got {type(value)}.

Error message

{name} must be a sequence of numbers, got {type(value)}.

What it means

`_coerce_embedding` validates that a value used as an embedding (either a fixed `embedding` argument or the return value of an `embedding_fn`) is a non-empty list or tuple of int/float. Anything else raises this TypeError, with `name` telling you which parameter failed. This catches bad mock configuration early instead of producing corrupt embeddings.

Source

Thrown at haystack/components/embedders/mock_utils.py:50

    :param dimension: The number of dimensions of the resulting embedding.
    :returns: A deterministic, L2-normalized embedding of length `dimension`.
    """
    digest = hashlib.sha256(text.encode("utf-8")).digest()
    seed = int.from_bytes(digest[:8], "big")
    rng = random.Random(seed)
    vector = [rng.uniform(-1.0, 1.0) for _ in range(dimension)]
    return _l2_normalize(vector)


def _coerce_embedding(value: object, *, name: str) -> list[float]:
    """
    Validate that `value` is a non-empty sequence of numbers and coerce it into a list of floats.

    :param value: The value to validate, e.g. a user-provided fixed embedding or the output of an `embedding_fn`.
    :param name: How to refer to `value` in error messages, e.g. ``"'embedding'"``.
    """
    if not isinstance(value, (list, tuple)) or not all(isinstance(item, (int, float)) for item in value):
        raise TypeError(f"{name} must be a sequence of numbers, got {type(value)}.")
    if len(value) == 0:
        raise ValueError(f"{name} must not be empty.")
    return [float(item) for item in value]


def _estimate_usage(texts: list[str]) -> dict[str, int]:
    """
    Roughly estimate token usage as whitespace-separated word counts.

    This is an approximation (not real tokenization) intended to give downstream code realistic-looking metadata.
    """
    prompt_tokens = sum(len(text.split()) for text in texts)
    return {"prompt_tokens": prompt_tokens, "total_tokens": prompt_tokens}

View on GitHub (pinned to e318778c9b)

Solutions

  1. Convert to a plain list of numbers first: `embedding=[float(x) for x in np.array_value]`
  2. Ensure `embedding_fn` returns a flat list/tuple of int/float, not strings, None, or nested lists
  3. Check the config/fixture supplying the embedding — it must be a JSON array of numbers

Example fix

// before
MockDocumentEmbedder(embedding=np.zeros(768))
// after
MockDocumentEmbedder(embedding=[0.0] * 768)
Defensive patterns

Strategy: type-guard

Validate before calling

def _valid_embedding(v):
    return isinstance(v, (list, tuple)) and len(v) > 0 and all(isinstance(x, (int, float)) for x in v)
assert _valid_embedding(embedding)
embedder = MockDocumentEmbedder(embedding=embedding)

Type guard

def is_numeric_sequence(value) -> bool:
    return isinstance(value, (list, tuple)) and all(isinstance(item, (int, float)) for item in value)

Try / catch

try:
    embedder = MockDocumentEmbedder(embedding=embedding)
except TypeError:
    embedding = [float(x) for x in embedding]  # e.g. numpy array or tensor
    embedder = MockDocumentEmbedder(embedding=embedding)

Prevention

When it happens

Trigger: `MockTextEmbedder(embedding="abc")`, `embedding=0.5` (scalar, not a sequence), `embedding_fn=lambda t: ["a", "b"]` (non-numeric items), or `embedding=np.array([...])` if numpy arrays are not list/tuple — passed via `MockDocumentEmbedder`/`MockTextEmbedder` `__init__` or returned from `_embed`.

Common situations: Passing a numpy array or torch tensor as a fixed embedding (not list/tuple); embedding_fn returning strings or nested lists; a JSON config providing a string instead of a numeric array.

Related errors


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