langchain-ai/langchain · error · NotImplementedError

add_message is not implemented for this class. Please implem

Error message

add_message is not implemented for this class. Please implement add_message or add_messages.

What it means

`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.

Source

Thrown at libs/core/langchain_core/chat_history.py:167

        """Add a Message object to the store.

        Args:
            message: A `BaseMessage` object to store.

        Raises:
            NotImplementedError: If the sub-class has not implemented an efficient
                `add_messages` method.
        """
        if type(self).add_messages != BaseChatMessageHistory.add_messages:
            # This means that the sub-class has implemented an efficient add_messages
            # method, so we should use it.
            self.add_messages([message])
        else:
            msg = (
                "add_message is not implemented for this class. "
                "Please implement add_message or add_messages."
            )
            raise NotImplementedError(msg)

    def add_messages(self, messages: Sequence[BaseMessage]) -> None:
        """Add a list of messages.

        Implementations should over-ride this method to handle bulk addition of messages
        in an efficient manner to avoid unnecessary round-trips to the underlying store.

        Args:
            messages: A sequence of `BaseMessage` objects to store.
        """
        for message in messages:
            self.add_message(message)

    async def aadd_messages(self, messages: Sequence[BaseMessage]) -> None:
        """Async add a list of messages.

        Args:
            messages: A sequence of `BaseMessage` objects to store.

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Implement `add_messages(messages)` (preferred — bulk, one round trip) or `add_message(message)` on your subclass
  2. If you only need storage, subclass and delegate: store messages in a list inside `add_messages`
  3. Ensure the override signature matches exactly so the dispatch check `type(self).add_messages != BaseChatMessageHistory.add_messages` sees it
  4. Add a unit test calling both add_message and add_messages on the subclass

Example fix

# before
class MyHistory(BaseChatMessageHistory):
    def clear(self) -> None: ...

# after
class MyHistory(BaseChatMessageHistory):
    def add_messages(self, messages: Sequence[BaseMessage]) -> None:
        self._store.extend(messages)
    def clear(self) -> None:
        self._store.clear()
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain_core.chat_history import BaseChatMessageHistory

def supports_writes(history: BaseChatMessageHistory) -> bool:
    implements_add_messages = type(history).add_messages is not BaseChatMessageHistory.add_messages
    implements_add = type(history).add_message is not BaseChatMessageHistory.add_message
    return implements_add_messages or implements_add

Type guard

from langchain_core.chat_history import BaseChatMessageHistory

def implements_write(history: BaseChatMessageHistory) -> bool:
    """True if the subclass actually implements add_message or add_messages."""
    return (
        type(history).add_messages is not BaseChatMessageHistory.add_messages
        or type(history).add_message is not BaseChatMessageHistory.add_message
    )

Prevention

When it happens

Trigger: 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.

Common situations: Building custom chat history backends (Redis, Postgres, files) and missing the write methods; partial copy-paste implementations; passing an unmodified base instance into `RunnableWithMessageHistory`.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/7a9e103563be5802. Report an issue: GitHub.