{"record":{"id":"e016da976e1a8d24","repo":"run-llama/llama_index","slug":"invalid-message-content-message-content-s","errorCode":null,"errorMessage":"Invalid message content: {message.content!s}","messagePattern":"Invalid message content: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/base/llms/base.py","lineNumber":84,"sourceCode":"        return {\"class_name\": self.class_name(), **self.metadata.model_dump()}\n\n    def convert_chat_messages(self, messages: Sequence[ChatMessage]) -> List[Any]:\n        \"\"\"Convert chat messages to an LLM specific message format.\"\"\"\n        converted_messages = []\n        for message in messages:\n            if isinstance(message.content, str):\n                converted_messages.append(message)\n            elif isinstance(message.content, List):\n                content_string = \"\"\n                for block in message.content:\n                    if isinstance(block, TextBlock):\n                        content_string += block.text\n                    else:\n                        raise ValueError(\"LLM only supports text inputs\")\n                message.content = content_string\n                converted_messages.append(message)\n            else:\n                raise ValueError(f\"Invalid message content: {message.content!s}\")\n\n        return converted_messages\n\n    @abstractmethod\n    def chat(self, messages: Sequence[ChatMessage], **kwargs: Any) -> ChatResponse:\n        \"\"\"\n        Chat endpoint for LLM.\n\n        Args:\n            messages (Sequence[ChatMessage]):\n                Sequence of chat messages.\n            kwargs (Any):\n                Additional keyword arguments to pass to the LLM.\n\n        Returns:\n            ChatResponse: Chat response from the LLM.\n\n        Examples:","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/base/llms/base.py#L66-L102","documentation":"Raised by BaseLLM.convert_chat_messages when a ChatMessage's content is neither a str nor a List (of blocks). The message content contract is string or block-list; anything else (int, dict, None, custom object) hits this branch with the offending value echoed via !s.","triggerScenarios":"Calling llm.chat with ChatMessage(content=123), content=None (non-defaulted), content={\"text\": ...}, or any non-str/non-list object; programmatic message builders that pass through unvalidated payloads.","commonSituations":"Passing parsed JSON or numbers from an API straight into ChatMessage; a None content slipping through when optional fields are forwarded; refactors changing content from str to dict.","solutions":["Ensure every ChatMessage content is a str: coerce with str(...) at construction.","For rich content, build a list of typed blocks: [TextBlock(text=...), ImageBlock(...)].","Validate messages before calling chat (see type guard below) and reject/normalize bad ones at your boundary."],"exampleFix":"# before\nmsg = ChatMessage(role=MessageRole.USER, content=payload[\"text\"] if \"text\" in payload else None)\n\n# after\ntext = str(payload.get(\"text\", \"\"))\nmsg = ChatMessage(role=MessageRole.USER, content=text)","handlingStrategy":"type-guard","validationCode":"msgs = [m if isinstance(m.content, (str, list)) and m.content else m.model_copy(update={\"content\": str(m.content or \"\")}) for m in msgs]","typeGuard":"def is_valid_content(c: Any) -> bool:\n    return isinstance(c, (str, list))","tryCatchPattern":null,"preventionTips":["Always construct ChatMessage content from str(...) of external data.","Never forward None/dict payloads into message content."],"tags":["llama-index","llm","chat-message","type-validation"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}