deepset-ai/haystack · error · ValueError
Unsupported tool result: {result.result}
Error message
Unsupported tool result: {result.result} What it means
Tool call results in the Responses API conversion accept either a str or a list of TextContent/ImageContent/FileContent as their `result`. Any other payload type (dict, None, nested objects) raises ValueError since it cannot be mapped to `output` content.
Source
Thrown at haystack/components/generators/chat/openai_responses.py:1027
# user message
if message._role.value == "user":
content = [convert_part(part) for part in message._content]
openai_msg["content"] = content
return [openai_msg]
# tool message
if tool_call_results:
formatted_tool_results = []
for result in tool_call_results:
if result.origin.id is not None:
# Handle multimodal tool results (list of TextContent/ImageContent/FileContent)
if isinstance(result.result, list):
output_content = [convert_part(part) for part in result.result]
elif isinstance(result.result, str):
output_content = [{"type": "input_text", "text": result.result}]
else:
raise ValueError(f"Unsupported tool result: {result.result}")
tool_result = {
"type": "function_call_output",
"call_id": result.origin.extra.get("call_id") if result.origin.extra else "",
"output": output_content,
}
formatted_tool_results.append(tool_result)
formatted_messages.extend(formatted_tool_results)
# Note: the API expects a reasoning id even if there is no reasoning text
# function calls without reasoning ids are not supported by the API
if reasonings:
formatted_reasonings = []
for reasoning in reasonings:
# Streaming events (e.g. response.reasoning_summary_text.delta) store event-level
# fields like item_id, output_index, summary_index, event_id, sequence_number into
# reasoning.extra. Those are not valid reasoning input item fields and the API
# rejects them with "Unknown parameter" when sent back in subsequent turns.
# Valid fields per ResponseReasoningItem schema: id, type, summary (handled separately),View on GitHub (pinned to e318778c9b)
Solutions
- Serialize the tool result before creating the ToolCallResult: json.dumps(result) or str(result)
- Convert structured results into a list of TextContent parts
- Check ToolCallResult.result type before sending the message
Example fix
// before
ToolCallResult(result={"answer": 42})
// after
import json
ToolCallResult(result=json.dumps({"answer": 42})) Defensive patterns
Strategy: validation
Validate before calling
from haystack.dataclasses import TextContent, ImageContent, FileContent
for m in messages:
for r in m.tool_call_results:
ok = isinstance(r.result, str) or (isinstance(r.result, list) and all(isinstance(p, (TextContent, ImageContent, FileContent)) for p in r.result))
assert ok, type(r.result) Type guard
def is_supported_tool_result(r) -> bool:
from haystack.dataclasses import TextContent, ImageContent, FileContent
return isinstance(r.result, str) or (isinstance(r.result, list) and all(isinstance(p, (TextContent, ImageContent, FileContent)) for p in r.result)) Try / catch
try:
gen.run(messages=messages)
except ValueError as e:
if "Unsupported tool result" in str(e):
messages = [stringify_tool_results(m) for m in messages] Prevention
- Serialize tool outputs to str (json.dumps) before wrapping
- Only use str or TextContent/ImageContent/FileContent lists
- Avoid dicts/None in ToolCallResult.result
When it happens
Trigger: Constructing a ToolCallResult whose `result` field is a dict/None/custom object, then passing the message through _convert_chat_message_to_responses_format.
Common situations: Returning parsed JSON objects or dicts from tools and stuffing them directly into ToolCallResult instead of serializing to a string.
Related errors
- For OpenAI compatibility, a `ChatMessage` with a `ToolCallRe
- OpenAIDocumentEmbedder expects a list of Documents as input.
- OpenAIDocumentEmbedder expects a list of Documents as input.
- OpenAITextEmbedder expects a string as an input.In case you
- 'response_fn' must return a string or ChatMessage, got {type
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/1c512088c90777d5.
Report an issue: GitHub.