deepset-ai/haystack · error · ValueError
ChatMessages from {role} role must contain text. Received Ch
Error message
ChatMessages from {role} role must contain text. Received ChatMessage with no text: {message} What it means
ChatPromptBuilder raises this in __init__ when a USER or SYSTEM ChatMessage passed as a Jinja template has text=None (e.g. a tool/function-call message with no textual content). Variable inference requires message.text to extract template variables, so the constructor fails fast.
Source
Thrown at haystack/components/builders/chat_prompt_builder.py:178
`template` parameter. For example, to use more variables during prompt engineering than the ones present
in the default template, you can provide them here.
"""
self._variables = variables
self._required_variables = required_variables
self.template = template
self._env = HaystackSandboxedEnvironment(extensions=[ChatMessageExtension])
if arrow_import.is_successful():
self._env.add_extension(Jinja2TimeExtension)
extracted_variables = []
if template and not variables:
if isinstance(template, list):
for message in template:
if message.is_from(ChatRole.USER) or message.is_from(ChatRole.SYSTEM):
# infer variables from template
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)
assigned_variables, template_variables = _extract_template_variables_and_assignments(
env=self._env, template=message.text
)
extracted_variables += list(template_variables - assigned_variables)
elif isinstance(template, str):
assigned_variables, template_variables = _extract_template_variables_and_assignments(
env=self._env, template=template
)
extracted_variables = list(template_variables - assigned_variables)
extracted_variables = extracted_variables or []
self.variables = variables or extracted_variables
self.required_variables = required_variables or []
if len(self.variables) > 0 and required_variables is None:
logger.warning(View on GitHub (pinned to e318778c9b)
Solutions
- Ensure every USER/SYSTEM ChatMessage in the template list has non-None text (use ChatMessage.from_user(text=...) / from_system(text=...)).
- Filter out messages without text before passing the list to ChatPromptBuilder.
- If you need non-text content in a template, use a string template plus variables instead of ChatMessage objects.
Example fix
// before msg = ChatMessage.from_function_call(call_obj) prompt = ChatPromptBuilder(template=[msg]) # text is None // after template = [m for m in messages if m.text is not None and m.is_from(ChatRole.USER) or m.is_from(ChatRole.SYSTEM)] prompt = ChatPromptBuilder(template=template)
Defensive patterns
Strategy: validation
Validate before calling
from haystack.dataclasses import ChatRole msgs = [m for m in template if m.text is not None or not (m.is_from(ChatRole.USER) or m.is_from(ChatRole.SYSTEM))]
Type guard
def has_text(m) -> bool:
return m.text is not None or not (m.is_from(ChatRole.USER) or m.is_from(ChatRole.SYSTEM)) Try / catch
try:
builder = ChatPromptBuilder(template=template)
except ValueError as e:
if 'must contain text' in str(e):
template = [m for m in template if m.text is not None]
builder = ChatPromptBuilder(template=template)
else:
raise Prevention
- Always construct USER/SYSTEM messages with explicit text.
- Filter deserialized chat histories for textless messages before templating.
- Add an assert/self-check helper for template lists in your pipeline setup.
When it happens
Trigger: Passing template as a list of ChatMessage where any USER or SYSTEM message was built without text content (e.g. ChatMessage.from_function_call or an empty message), then instantiating ChatPromptBuilder(template=[...]).
Common situations: Building a prompt list from deserialized or programmatically constructed messages where tool-call payloads replaced the text; copying messages from a chat log where the first system message has no text.
Related errors
- The templatize_part filter cannot be used with a template co
- The {self.__class__.__name__} requires a non-empty list of C
- The {self.__class__.__name__} expects a list containing only
- Missing required input variables in ChatPromptBuilder: {miss
- The prompt must not have any variables, only instructions on
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/fe8f19accc5c7bc3.
Report an issue: GitHub.