deepset-ai/haystack · error · ValueError
The {self.__class__.__name__} expects a list containing only
Error message
The {self.__class__.__name__} expects a list containing only ChatMessage instances. The provided list contains other types. Please ensure that all elements in the list are ChatMessage instances. What it means
ChatPromptBuilder.run raises when a list template is supplied but one or more elements are not ChatMessage instances. The builder can only render ChatMessage templates, so mixed or wrong-typed lists are rejected.
Source
Thrown at haystack/components/builders/chat_prompt_builder.py:253
- `prompt`: The updated list of `ChatMessage` objects after rendering the templates.
:raises ValueError:
If `chat_messages` is empty or contains elements that are not instances of `ChatMessage`.
"""
kwargs = kwargs or {}
template_variables = template_variables or {}
template_variables_combined = {**kwargs, **template_variables}
if template is None:
template = self.template
if not template:
raise ValueError(
f"The {self.__class__.__name__} requires a non-empty list of ChatMessage instances. "
f"Please provide a valid list of ChatMessage instances to render the prompt."
)
if isinstance(template, list) and not all(isinstance(message, ChatMessage) for message in template):
raise ValueError(
f"The {self.__class__.__name__} expects a list containing only ChatMessage instances. "
f"The provided list contains other types. Please ensure that all elements in the list "
f"are ChatMessage instances."
)
processed_messages = []
if isinstance(template, list):
for message in template:
if message.is_from(ChatRole.USER) or message.is_from(ChatRole.SYSTEM):
self._validate_variables(set(template_variables_combined.keys()))
if message.text is None:
raise ValueError(NO_TEXT_ERROR_MESSAGE.format(role=message.role.value, message=message))
if message.text and "templatize_part" in message.text:
raise ValueError(FILTER_NOT_ALLOWED_ERROR_MESSAGE)
compiled_template = self._env.from_string(message.text)
rendered_text = compiled_template.render(template_variables_combined)
# use dataclasses.replace to avoid in-place mutation of the original message
rendered_message: ChatMessage = replace(message, _content=[TextContent(text=rendered_text)])View on GitHub (pinned to e318778c9b)
Solutions
- Wrap plain strings in ChatMessage objects, e.g. ChatMessage.from_user(text).
- Validate all elements with isinstance(m, ChatMessage) before calling run.
- If you have string templates, use PromptBuilder or convert them to ChatMessage lists first.
Example fix
// before
builder.run(template=['Hello {{ name }}'])
// after
builder.run(template=[ChatMessage.from_user('Hello {{ name }}')]) Defensive patterns
Strategy: type-guard
Validate before calling
from haystack.dataclasses import ChatMessage assert all(isinstance(m, ChatMessage) for m in template), 'all elements must be ChatMessage'
Type guard
def all_chat_messages(t: list) -> bool:
return isinstance(t, list) and all(isinstance(m, ChatMessage) for m in t) Try / catch
try:
res = builder.run(template=template, **kwargs)
except ValueError as e:
if 'only ChatMessage instances' in str(e):
template = [ChatMessage.from_user(m) if isinstance(m, str) else m for m in template]
res = builder.run(template=template, **kwargs)
else:
raise Prevention
- Normalize incoming prompt data to ChatMessage objects at pipeline boundaries.
- Avoid mixing raw strings with ChatMessage objects in template lists.
- Use a shared helper to build template lists.
When it happens
Trigger: Calling run(template=[...]) where the list contains plain strings, dicts, or a mix of str and ChatMessage.
Common situations: Reusing a PromptBuilder-style string list; constructing messages by hand and accidentally appending raw strings; deserialization returning dicts instead of ChatMessage objects.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- ChatMessages from {role} role must contain text. Received Ch
- The templatize_part filter cannot be used with a template co
- The {self.__class__.__name__} requires a non-empty list of C
- Missing required input variables in ChatPromptBuilder: {miss
- {name} must be a sequence of numbers, got {type(value)}.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/88a5860486befc50.
Report an issue: GitHub.