deepset-ai/haystack · error · ValueError

StateSchema: 'messages' must be of type list[ChatMessage], g

Error message

StateSchema: 'messages' must be of type list[ChatMessage], got {definition['type']}

What it means

StateSchema validation raises this ValueError when the special 'messages' key is declared with a type that is not a list type. The reserved 'messages' parameter must be list-typed because the Agent stores conversation history there.

Source

Thrown at haystack/components/agents/state/state.py:76

    """
    Validate that a schema dictionary meets all required constraints.

    Checks that each parameter definition has a valid type field and that any handler
    specified is a callable function.

    :param schema: Dictionary mapping parameter names to their type and handler configs
    :raises ValueError: If schema validation fails due to missing or invalid fields
    """
    for param, definition in schema.items():
        if "type" not in definition:
            raise ValueError(f"StateSchema: Key '{param}' is missing a 'type' entry.")
        if not _is_valid_type(definition["type"]):
            raise ValueError(f"StateSchema: 'type' for key '{param}' must be a Python type, got {definition['type']}")
        if definition.get("handler") is not None and not callable(definition["handler"]):
            raise ValueError(f"StateSchema: 'handler' for key '{param}' must be callable or None")
        if param == "messages":  # definition["type"] != list[ChatMessage] but split to cover also List[ChatMessage]
            if not _is_list_type(definition["type"]):
                raise ValueError(f"StateSchema: 'messages' must be of type list[ChatMessage], got {definition['type']}")
            # Check if the list contains ChatMessage elements
            args = get_args(definition["type"])
            if not args or not issubclass(args[0], ChatMessage):
                raise ValueError(f"StateSchema: 'messages' must be of type list[ChatMessage], got {definition['type']}")


class State:
    """
    State is a container for storing shared information during the execution of an Agent and its tools.

    For instance, State can be used to store documents, context, and intermediate results.

    Internally it wraps a `_data` dictionary defined by a `schema`. Each schema entry has:
    ```json
      "parameter_name": {
        "type": SomeType,  # expected type
        "handler": Optional[Callable[[Any, Any], Any]]  # merge/update function
      }

View on GitHub (pinned to e318778c9b)

Solutions

  1. Declare messages as list[ChatMessage]: {"messages": {"type": list[ChatMessage]}}
  2. Use typing.List[ChatMessage] if using older typing style — both are accepted
  3. Never declare 'messages' as a scalar type

Example fix

// before
schema = {"messages": {"type": ChatMessage}}
// after
schema = {"messages": {"type": list[ChatMessage]}}
Defensive patterns

Strategy: validation

Validate before calling

from haystack.dataclasses import ChatMessage
def messages_key_valid(schema):
    t = schema.get("messages", {}).get("type")
    import typing
    return t is None or (typing.get_origin(t) is list)

Type guard

import typing
from haystack.dataclasses import ChatMessage
def is_message_list_type(t) -> bool:
    return typing.get_origin(t) in (list,) and \
           typing.get_args(t) and typing.get_args(t)[0] is ChatMessage

Try / catch

try:
    schema = StateSchema(my_schema)
except ValueError as e:
    if "'messages' must be of type" in str(e):
        my_schema["messages"]["type"] = list[ChatMessage]
    else:
        raise

Prevention

When it happens

Trigger: Defining schema={"messages": {"type": ChatMessage}} or {"type": str} — any non-list type for the 'messages' key.

Common situations: Copy-pasting a generic schema entry for 'messages', or intending to store a single ChatMessage instead of the required list.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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