langchain-ai/langchain · error · NotImplementedError
Unsupported operand type for +: {type(other)}
Error message
Unsupported operand type for +: {type(other)} What it means
ChatPromptTemplate.__add__ supports concatenating a string, list, or tuple of messages/templates on the right side; anything else raises NotImplementedError('Unsupported operand type for +: {type}'). This operator is a convenience for extending a prompt, not general addition — ints, dicts, other prompt objects (non-chat), or Runnables are rejected.
Source
Thrown at libs/core/langchain_core/prompts/chat.py:1049
)
if isinstance(
other, (BaseMessagePromptTemplate, BaseMessage, BaseChatPromptTemplate)
):
return ChatPromptTemplate(messages=[*self.messages, other]).partial(
**partials
)
if isinstance(other, (list, tuple)):
other_ = ChatPromptTemplate.from_messages(other)
return ChatPromptTemplate(messages=self.messages + other_.messages).partial(
**partials
)
if isinstance(other, str):
prompt = HumanMessagePromptTemplate.from_template(other)
return ChatPromptTemplate(messages=[*self.messages, prompt]).partial(
**partials
)
msg = f"Unsupported operand type for +: {type(other)}"
raise NotImplementedError(msg)
@model_validator(mode="before")
@classmethod
def validate_input_variables(cls, values: dict[str, Any]) -> Any:
"""Validate input variables.
If `input_variables` is not set, it will be set to the union of all input
variables in the messages.
Args:
values: values to validate.
Returns:
Validated values.
Raises:
ValueError: If input variables do not match.
"""View on GitHub (pinned to e32fa9a52e)
Solutions
- Wrap the right side in a list: prompt + [message_or_template]
- For plain text, add the string directly: prompt + "Summarize the above" (becomes a human message)
- To compose two ChatPromptTemplates, use ChatPromptTemplate.from_messages([*p1.messages, *p2.messages])
Example fix
# before
merged = base_prompt + followup_prompt # NotImplementedError (not str/list/tuple path)
# after
merged = ChatPromptTemplate.from_messages(
[*base_prompt.messages, *followup_prompt.messages]
) Defensive patterns
Strategy: type-guard
Validate before calling
def add_to_prompt(prompt, other):
if isinstance(other, (str, list, tuple)):
return prompt + other
msg = f"cannot add {type(other)} to ChatPromptTemplate; wrap in a list"
raise TypeError(msg) Type guard
def is_addable_to_chat_prompt(other) -> bool:
return isinstance(other, (str, list, tuple)) Try / catch
try:
merged = prompt + other
except NotImplementedError:
merged = prompt + [other] # wrap and retry Prevention
- Always wrap single messages or templates in a list when using +
- Compose two ChatPromptTemplates via from_messages([*a.messages, *b.messages])
When it happens
Trigger: prompt + 5, prompt + {'role': ...}, prompt + some_string_generator, or prompt + another_prompt where the right side is not one of str/list/tuple. Note a bare dict is NOT accepted even though from_messages accepts dict elements inside a list.
Common situations: Developers assume prompt1 + prompt2 composes two ChatPromptTemplates; or splat a **kwargs dict onto +; or add a single message object instead of wrapping it in a list.
Related errors
- variable {self.variable_name} should be a list of base messa
- Partial variables are not supported for list of templates.
- Only one format variable allowed per image template.\nGot: {
- Invalid image template: {tmpl}
- jinja2 is unsafe and is not supported for templates expresse
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/8abdf08356d5e3c0.
Report an issue: GitHub.