deepset-ai/haystack · error · ValueError
A `ChatMessage` must contain at least one `TextContent`, `To
Error message
A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`, or `ImageContent`.
What it means
ValueError raised in `convert_message_to_hf_format` when a ChatMessage's content list contains none of the content types the Hugging Face API can represent: TextContent, ToolCall, ToolCallResult, or ImageContent. ReasoningContent is deliberately excluded from this validation because it is for human transparency only and is never sent to the API, so a message containing only ReasoningContent is treated as empty.
Source
Thrown at haystack/utils/hf.py:73
"""
Convert a message to the format expected by Hugging Face.
Note: ReasoningContent is skipped during conversion because the HuggingFace Inference API
(which follows the OpenAI-compatible chat completion format) does not support reasoning
in input messages. Reasoning is captured from model outputs for transparency but is not
sent back to the API in multi-turn conversations.
"""
text_contents = message.texts
tool_calls = message.tool_calls
tool_call_results = message.tool_call_results
images = message.images
# Filter out ReasoningContent from the content list for validation
# ReasoningContent is for human transparency only, not sent to the API
non_reasoning_content = [c for c in message._content if not isinstance(c, ReasoningContent)]
if not text_contents and not tool_calls and not tool_call_results and not images:
raise ValueError(
"A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`, or `ImageContent`."
)
if len(tool_call_results) > 0 and len(non_reasoning_content) > 1:
raise ValueError(
"For compatibility with the Hugging Face API, a `ChatMessage` with a `ToolCallResult` "
"cannot contain any other content."
)
# HF always expects a content field, even if it is empty
hf_msg: dict[str, Any] = {"role": message._role.value, "content": ""}
if tool_call_results:
result = tool_call_results[0]
hf_msg["content"] = result.result
if tc_id := result.origin.id:
hf_msg["tool_call_id"] = tc_id
# HF does not provide a way to communicate errors in tool invocations, so we ignore the error field
return hf_msgView on GitHub (pinned to e318778c9b)
Solutions
- Ensure the ChatMessage contains at least one TextContent, ToolCall, ToolCallResult, or ImageContent before conversion
- If the message only holds ReasoningContent, skip sending it to the generator or append a fallback TextContent
- Use ChatMessage.from_assistant/from_user with non-empty content
Example fix
// before
msg = ChatMessage.from_assistant("") # or only ReasoningContent
hf = convert_message_to_hf_format(msg)
// after
msg = ChatMessage.from_assistant("Here is the answer.")
hf = convert_message_to_hf_format(msg) Defensive patterns
Strategy: validation
Validate before calling
from haystack.dataclasses import TextContent, ToolCall, ToolCallResult, ImageContent
from haystack.utils import ReasoningContent
def is_hf_convertible(msg) -> bool:
return any(not isinstance(c, ReasoningContent) for c in msg._content) Type guard
def has_sendable_content(msg) -> bool:
from haystack.dataclasses import TextContent, ToolCall, ToolCallResult, ImageContent
return any(isinstance(c, (TextContent, ToolCall, ToolCallResult, ImageContent)) for c in msg._content) Try / catch
try:
hf_msg = convert_message_to_hf_format(msg)
except ValueError:
hf_msg = None # skip message or substitute a placeholder TextContent Prevention
- Never send messages containing only ReasoningContent to HF generators
- Construct messages with ChatMessage.from_assistant/from_user with non-empty text
- Filter out reasoning-only messages from the chat history before conversion
When it happens
Trigger: Calling convert_message_to_hf_format (or HuggingFaceAPIChatGenerator, which uses it) with a ChatMessage built solely from ReasoningContent, or from an empty content list, e.g. ChatMessage.from_assistant('') with no tool calls or images.
Common situations: Constructing assistant messages from LLM responses that contained only reasoning/thinking content; stripping content from a message during preprocessing; serializing placeholder messages.
Related errors
- For compatibility with the Hugging Face API, a `ChatMessage`
- Message template produced content that couldn't be parsed in
- A `ChatMessage` must contain at least one `TextContent`, `To
- Component named {receiver_component_name} not found in the p
- Component named {name} not found in the pipeline.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/8914d1ae82d166e8.
Report an issue: GitHub.