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
- Start a new accumulator per function name / per tool invocation
- Guard merges: only `+` when `self.name == other.name`
- 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
- Buffer function chunks per name, not globally
- Migrate legacy FunctionMessage code to ToolMessage with tool_call_ids
- Reset accumulators at tool-output boundaries in stream handlers
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
- Cannot concatenate ChatMessageChunks with different roles.
- This output parser can only be used with a chat generation.
- Could not parse function call: {exc}
- SyncTextProjection requires a string delta
- SyncTextProjection requires a string final value
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/b4e5751aa10bfaf1.
Report an issue: GitHub.