{"record":{"id":"bc96298c5faf38f7","repo":"deepset-ai/haystack","slug":"a-chatmessage-must-contain-at-least-one-textcon","errorCode":null,"errorMessage":"A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`,\n              `ImageContent`, `FileContent`, `ReasoningContent`.","messagePattern":"A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`,\n              `ImageContent`, `FileContent`, `ReasoningContent`\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/generators/chat/openai_responses.py","lineNumber":996,"sourceCode":"        if isinstance(part, FileContent):\n            return {\n                \"type\": \"input_file\",\n                # Filename is optional but if not provided, OpenAI expects a file_id of a previous file upload.\n                # We use a dummy filename to avoid this issue.\n                \"filename\": part.filename or \"filename\",\n                \"file_data\": f\"data:{part.mime_type or 'application/pdf'};base64,{part.base64_data}\",\n            }\n        raise ValueError(f\"Unsupported content type: {type(part)}\")\n\n    text_contents = message.texts\n    tool_calls = message.tool_calls\n    tool_call_results = message.tool_call_results\n    images = message.images\n    reasonings = message.reasonings\n    files = message.files\n\n    if not any([text_contents, tool_calls, tool_call_results, images, reasonings, files]):\n        raise ValueError(\n            \"\"\"A `ChatMessage` must contain at least one `TextContent`, `ToolCall`, `ToolCallResult`,\n              `ImageContent`, `FileContent`, or `ReasoningContent`.\"\"\"\n        )\n    if len(tool_call_results) > 0 and len(message._content) > 1:\n        raise ValueError(\n            \"For OpenAI compatibility, a `ChatMessage` with a `ToolCallResult` cannot contain any other content.\"\n        )\n\n    formatted_messages: list[dict[str, Any]] = []\n    openai_msg: dict[str, Any] = {\"role\": message._role.value}\n    if message._name is not None:\n        openai_msg[\"name\"] = message._name\n\n    # user message\n    if message._role.value == \"user\":\n        content = [convert_part(part) for part in message._content]\n        openai_msg[\"content\"] = content\n        return [openai_msg]","sourceCodeStart":978,"sourceCodeEnd":1014,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/generators/chat/openai_responses.py#L978-L1014","documentation":"A ChatMessage with an empty content list cannot be serialized for the OpenAI Responses API; haystack raises ValueError because the API requires at least one content item (text, tool call, tool result, image, file, or reasoning).","triggerScenarios":"Calling OpenAIResponsesChatGenerator.run/count with a ChatMessage constructed with no contents, e.g. ChatMessage(_role=ChatRole.USER, _content=[]).","commonSituations":"Building messages dynamically where all branches skipped adding content; filtering out contents (e.g. stripping images) leaving an empty message.","solutions":["Ensure every message passed to the generator has at least one content part","Skip or drop empty messages from the message list before run()","Add a placeholder TextContent if the message must be sent"],"exampleFix":"// before\nmsg = ChatMessage(_role=ChatRole.USER, _content=[])\n// after\nmsg = ChatMessage.from_user(\"(empty)\") if not contents else ChatMessage(_role=ChatRole.USER, _content=contents)","handlingStrategy":"validation","validationCode":"for m in messages:\n    if not m._content:\n        raise ValueError(\"message has no content\")  # or drop it","typeGuard":"def has_content(m) -> bool:\n    return bool(m._content)","tryCatchPattern":"try:\n    gen.run(messages=messages)\nexcept ValueError as e:\n    if \"must contain at least one\" in str(e):\n        messages = [m for m in messages if m._content]\n        gen.run(messages=messages)","preventionTips":["Filter empty messages before run()","Never construct ChatMessage with _content=[]","Assert message._content after dynamic building"],"tags":["python","haystack","openai","empty-content","validation"],"backgroundTag":"empty-message-content","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}