langchain-ai/langchain · error · ValueError

Cannot concatenate FunctionMessageChunks with different name

Error message

Cannot concatenate FunctionMessageChunks with different names.

What it means

Raised by FunctionMessageChunk.__add__ when two chunks whose `name` attributes differ are merged with `+`. Chunks of a legacy FunctionMessage belong to one function invocation identified by name; merging across names would corrupt that identity, so it is rejected.

Source

Thrown at libs/core/langchain_core/messages/function.py:48

    type: Literal["function"] = "function"
    """The type of the message (used for serialization)."""


class FunctionMessageChunk(FunctionMessage, BaseMessageChunk):
    """Function Message chunk."""

    # Ignoring mypy re-assignment here since we're overriding the value
    # to make sure that the chunk variant can be discriminated from the
    # non-chunk variant.
    type: Literal["FunctionMessageChunk"] = "FunctionMessageChunk"  # type: ignore[assignment]
    """The type of the message (used for serialization)."""

    @override
    def __add__(self, other: Any) -> BaseMessageChunk:  # type: ignore[override]
        if isinstance(other, FunctionMessageChunk):
            if self.name != other.name:
                msg = "Cannot concatenate FunctionMessageChunks with different names."
                raise ValueError(msg)

            return self.__class__(
                name=self.name,
                content=merge_content(self.content, other.content),
                additional_kwargs=merge_dicts(
                    self.additional_kwargs, other.additional_kwargs
                ),
                response_metadata=merge_dicts(
                    self.response_metadata, other.response_metadata
                ),
                id=self.id,
            )

        return super().__add__(other)

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Start a new accumulator per function name / per tool invocation
  2. Guard merges: only `+` when `self.name == other.name`
  3. Migrate from FunctionMessage to the modern `ToolMessage`/tool_calls API, which keys merges by tool_call_id

Example fix

# before
acc = None
for chunk in function_chunks:
    acc = chunk if acc is None else acc + chunk  # ValueError across names

# after
buffers = {}
for chunk in function_chunks:
    buffers[chunk.name] = buffers.get(chunk.name, None) + chunk if buffers.get(chunk.name) else chunk
Defensive patterns

Strategy: type-guard

Validate before calling

def same_name(a, b) -> bool:
    return getattr(a, "name", None) == getattr(b, "name", None)

Type guard

from langchain_core.messages import FunctionMessageChunk

def is_same_function_chunk(a: FunctionMessageChunk, b: FunctionMessageChunk) -> bool:
    return a.name == b.name

Prevention

When it happens

Trigger: `chunk1 + chunk2` where `chunk1.name == "search"` and `chunk2.name == "calculate"`; accumulating streamed FunctionMessageChunks from multiple tool outputs into one buffer without resetting between tools.

Common situations: Legacy (pre-tool-calls API) streaming code that reduces all function chunks in a turn; parallel function calls whose outputs are interleaved in one stream; old agents migrated forward that still use FunctionMessage.

Related errors


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