{"record":{"id":"54a88797552a4c42","repo":"deepset-ai/haystack","slug":"expected-chatmessage-object-got-type-last-messag","errorCode":null,"errorMessage":"Expected ChatMessage object, got {type(last_message)}","messagePattern":"Expected ChatMessage object, got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"haystack/components/extractors/regex_text_extractor.py","lineNumber":122,"sourceCode":"            logger.warning(\"Received empty list of messages\")\n            return {\"captured_text\": \"\"}\n        return self._process_last_message(text_or_messages)\n\n    def _build_result(self, result: str | list[str]) -> dict:\n        \"\"\"Helper method to build the return dictionary based on configuration.\"\"\"\n        if (isinstance(result, str) and result == \"\") or (isinstance(result, list) and not result):\n            return {\"captured_text\": \"\"}\n        return {\"captured_text\": result}\n\n    def _process_last_message(self, messages: list[ChatMessage]) -> dict:\n        \"\"\"\n        Process only the last message and build the result.\n\n        :raises TypeError: If the last element of the list is not a ChatMessage instance.\n        \"\"\"\n        last_message = messages[-1]\n        if not isinstance(last_message, ChatMessage):\n            raise TypeError(f\"Expected ChatMessage object, got {type(last_message)}\")\n        if last_message.text is None:\n            logger.warning(\"Last message has no text content\")\n            return {\"captured_text\": \"\"}\n        result = self._extract_from_text(last_message.text)\n        return self._build_result(result)\n\n    def _extract_from_text(self, text: str) -> str | list[str]:\n        \"\"\"\n        Extract text using the regex pattern.\n\n        :param text:\n            The text to search through.\n\n        :returns:\n            The text captured by the first capturing group in the regex pattern.\n            If the pattern has no capture groups, returns the entire match.\n            If no match is found, returns an empty string.\n        \"\"\"","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/extractors/regex_text_extractor.py#L104-L140","documentation":"RegexTextExtractor processes the input list and expects its last element to be a ChatMessage. If the last element is any other type (e.g. a plain string or Document), _process_last_message raises TypeError naming the received type.","triggerScenarios":"Calling run(messages=[...]) where messages[-1] is not a ChatMessage instance — e.g. feeding raw strings from a custom component, or an upstream component emitting Documents instead of chat messages.","commonSituations":"Connecting a non-chat component's output to the extractor; manually constructing test inputs as strings; migration from string-based to chat-message-based pipelines.","solutions":["Ensure the input is a list whose last element is a ChatMessage, e.g. run(messages=[ChatMessage.from_user(text)])","Convert strings before passing: ChatMessage.from_user(my_string)","Check the upstream component's output type and add an adapter component if it emits non-ChatMessage values"],"exampleFix":"// before\nextractor.run(messages=[\"some plain text\"])\n// after\nfrom haystack.dataclasses import ChatMessage\nextractor.run(messages=[ChatMessage.from_user(\"some plain text\")])","handlingStrategy":"type-guard","validationCode":"if not messages or not isinstance(messages[-1], ChatMessage):\n    raise TypeError(\"Last message must be a ChatMessage\")","typeGuard":"from haystack.dataclasses import ChatMessage\n\ndef is_chat_message_list(messages: list) -> bool:\n    return bool(messages) and isinstance(messages[-1], ChatMessage)","tryCatchPattern":"try:\n    result = extractor.run(messages=messages)\nexcept TypeError as e:\n    logger.error(\"RegexTextExtractor input error: %s\", e)\n    raise","preventionTips":["Feed the extractor from chat-message-producing components only","Wrap raw strings with ChatMessage.from_user before passing","Check pipeline connection types to catch mismatched sockets at connect time"],"tags":["python","type-error","validation"],"backgroundTag":"unexpected-argument-type","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}