deepset-ai/haystack · error · ValueError

StateSchema: 'type' for key '{param}' must be a Python type,

Error message

StateSchema: 'type' for key '{param}' must be a Python type, got {definition['type']}

What it means

StateSchema validation raises this ValueError when the 'type' entry of a schema key is not recognized as a valid Python type by _is_valid_type (e.g. a string like 'list' or an arbitrary object instead of an actual type).

Source

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

    return deserialized_schema


def _validate_schema(schema: dict[str, Any]) -> None:
    """
    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:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Use the actual Python type object: list, not "list"
  2. If the schema was JSON-serialized, map string names back to types on load (e.g. via a lookup dict)
  3. Verify the value with isinstance(value, type) before constructing StateSchema

Example fix

// before
schema = {"numbers": {"type": "list"}}
// after
schema = {"numbers": {"type": list}}
Defensive patterns

Strategy: type-guard

Validate before calling

def types_are_types(schema):
    return all(isinstance(d.get("type"), type) or
               (hasattr(d.get("type"), "__origin__")) for d in schema.values())

Type guard

def is_real_type(t) -> bool:
    import types, typing
    return isinstance(t, type) or typing.get_origin(t) is not None

Try / catch

try:
    schema = StateSchema(my_schema)
except ValueError as e:
    if "must be a Python type" in str(e):
        my_schema = {k: {**v, "type": TYPE_LOOKUP[str(v['type'])]} for k, v in my_schema.items()}
    else:
        raise

Prevention

When it happens

Trigger: Passing {"param": {"type": "list"}} (string instead of type), or a non-type value like a dict or instance as the 'type' entry.

Common situations: Serializing schemas to JSON (types become strings) and loading them back without conversion, or confusing typing annotations like List[int] patterns unsupported by _is_valid_type.

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/c296010294b2c905. Report an issue: GitHub.