{"record":{"id":"7a9e103563be5802","repo":"langchain-ai/langchain","slug":"add-message-is-not-implemented-for-this-class-ple","errorCode":null,"errorMessage":"add_message is not implemented for this class. Please implement add_message or add_messages.","messagePattern":"add_message is not implemented for this class\\. Please implement add_message or add_messages\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/chat_history.py","lineNumber":167,"sourceCode":"        \"\"\"Add a Message object to the store.\n\n        Args:\n            message: A `BaseMessage` object to store.\n\n        Raises:\n            NotImplementedError: If the sub-class has not implemented an efficient\n                `add_messages` method.\n        \"\"\"\n        if type(self).add_messages != BaseChatMessageHistory.add_messages:\n            # This means that the sub-class has implemented an efficient add_messages\n            # method, so we should use it.\n            self.add_messages([message])\n        else:\n            msg = (\n                \"add_message is not implemented for this class. \"\n                \"Please implement add_message or add_messages.\"\n            )\n            raise NotImplementedError(msg)\n\n    def add_messages(self, messages: Sequence[BaseMessage]) -> None:\n        \"\"\"Add a list of messages.\n\n        Implementations should over-ride this method to handle bulk addition of messages\n        in an efficient manner to avoid unnecessary round-trips to the underlying store.\n\n        Args:\n            messages: A sequence of `BaseMessage` objects to store.\n        \"\"\"\n        for message in messages:\n            self.add_message(message)\n\n    async def aadd_messages(self, messages: Sequence[BaseMessage]) -> None:\n        \"\"\"Async add a list of messages.\n\n        Args:\n            messages: A sequence of `BaseMessage` objects to store.","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/chat_history.py#L149-L185","documentation":"`BaseChatMessageHistory.add_message` (chat_history.py) implements only `add_messages`, and `add_messages` defaults to looping `add_message`. If a subclass overrides neither, calling `add_message` raises `NotImplementedError` telling you to implement one of the two. The base class deliberately avoids abstractmethod to stay usable as a trivial in-memory store ancestor.","triggerScenarios":"Instantiating `BaseChatMessageHistory` (or a subclass that only overrides unrelated methods like `clear`) and calling `.add_message(...)`; custom history classes that implement `get_messages`/`clear` but forget writes; test doubles subclassing the base without write support.","commonSituations":"Building custom chat history backends (Redis, Postgres, files) and missing the write methods; partial copy-paste implementations; passing an unmodified base instance into `RunnableWithMessageHistory`.","solutions":["Implement `add_messages(messages)` (preferred — bulk, one round trip) or `add_message(message)` on your subclass","If you only need storage, subclass and delegate: store messages in a list inside `add_messages`","Ensure the override signature matches exactly so the dispatch check `type(self).add_messages != BaseChatMessageHistory.add_messages` sees it","Add a unit test calling both add_message and add_messages on the subclass"],"exampleFix":"# before\nclass MyHistory(BaseChatMessageHistory):\n    def clear(self) -> None: ...\n\n# after\nclass MyHistory(BaseChatMessageHistory):\n    def add_messages(self, messages: Sequence[BaseMessage]) -> None:\n        self._store.extend(messages)\n    def clear(self) -> None:\n        self._store.clear()","handlingStrategy":"type-guard","validationCode":"from langchain_core.chat_history import BaseChatMessageHistory\n\ndef supports_writes(history: BaseChatMessageHistory) -> bool:\n    implements_add_messages = type(history).add_messages is not BaseChatMessageHistory.add_messages\n    implements_add = type(history).add_message is not BaseChatMessageHistory.add_message\n    return implements_add_messages or implements_add","typeGuard":"from langchain_core.chat_history import BaseChatMessageHistory\n\ndef implements_write(history: BaseChatMessageHistory) -> bool:\n    \"\"\"True if the subclass actually implements add_message or add_messages.\"\"\"\n    return (\n        type(history).add_messages is not BaseChatMessageHistory.add_messages\n        or type(history).add_message is not BaseChatMessageHistory.add_message\n    )","tryCatchPattern":null,"preventionTips":["Implement add_messages (bulk) on every custom history class","Add an abstract-ish conformance test: add_message and add_messages both work","Don't instantiate BaseChatMessageHistory directly as a no-op store"],"tags":["chat-history","interface","not-implemented"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}