langchain-ai/langchain · error · TypeError

unsupported operand type(s) for +: "{self.__class__.__name__

Error message

unsupported operand type(s) for +: "{self.__class__.__name__}" and "{other.__class__.__name__}"

What it means

Raised by BaseMessage.__add__ when you use the + operator on two message objects whose types are incompatible for merging. langchain-core only merges messages when one is an instance of the other's class (e.g. AIMessageChunk + AIMessageChunk); anything else falls through to this TypeError, mirroring Python's behavior for unsupported operands.

Source

Thrown at libs/core/langchain_core/messages/base.py:471

            content = merge_content(self.content, *(o.content for o in other))
            additional_kwargs = merge_dicts(
                self.additional_kwargs, *(o.additional_kwargs for o in other)
            )
            response_metadata = merge_dicts(
                self.response_metadata, *(o.response_metadata for o in other)
            )
            return self.__class__(  # type: ignore[call-arg]
                id=self.id,
                content=content,
                additional_kwargs=additional_kwargs,
                response_metadata=response_metadata,
            )
        msg = (
            'unsupported operand type(s) for +: "'
            f"{self.__class__.__name__}"
            f'" and "{other.__class__.__name__}"'
        )
        raise TypeError(msg)


def message_to_dict(message: BaseMessage) -> dict[str, Any]:
    """Convert a Message to a dictionary.

    Args:
        message: Message to convert.

    Returns:
        Message as a dict. The dict will have a `type` key with the message type
        and a `data` key with the message data as a dict.

    """
    return {"type": message.type, "data": message.model_dump()}


def messages_to_dict(messages: Sequence[BaseMessage]) -> list[dict[str, Any]]:
    """Convert a sequence of Messages to a list of dictionaries.

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Put messages in a list (`[msg1, msg2]`) instead of using `+` — conversation history is a list, not a merged message
  2. If you meant to merge content, concatenate explicitly: `self.__class__(content=merge_content(msg1.content, msg2.content))`
  3. If merging streamed chunks, ensure both operands are the same chunk class (e.g. both `AIMessageChunk`) from the same provider run
  4. Check types before adding: `if type(other) is type(self): merged = self + other`

Example fix

# before
merged = HumanMessage("hi") + AIMessage("hello")  # TypeError

# after
history = [HumanMessage("hi"), AIMessage("hello")]
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain_core.messages import BaseMessage

def can_add(a: BaseMessage, b: BaseMessage) -> bool:
    return isinstance(b, type(a)) or isinstance(a, type(b))

Type guard

from langchain_core.messages import BaseMessage

def is_mergeable_pair(a: BaseMessage, b: BaseMessage) -> bool:
    """True when a + b is defined by BaseMessage.__add__."""
    return isinstance(b, type(a)) or isinstance(a, type(b))

Try / catch

try:
    merged = msg1 + msg2
except TypeError as e:
    if "unsupported operand type(s) for +" in str(e):
        merged = None  # keep as separate messages
    else:
        raise

Prevention

When it happens

Trigger: Calling `msg1 + msg2` where the operands are different message classes, e.g. `AIMessage('a') + HumanMessage('b')`, `HumanMessage('a') + AIMessageChunk('b')`, or adding a plain string/other object to a message. Only same-class (or chunk-of-same-base) combinations merge.

Common situations: Accidentally building a history list and reducing it with `sum()` or `+` over mixed Human/AI messages; mixing a chunk streamed from a provider with a locally constructed message of a different type; assuming `+` concatenates any message contents like strings.

Related errors


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