langchain-ai/langchain · error · ValueError
Expected str, BaseMessage, list[BaseMessage], or tuple[BaseM
Error message
Expected str, BaseMessage, list[BaseMessage], or tuple[BaseMessage]. Got {output_val}. What it means
The mirror of the input check for outputs: _get_output_messages must turn the wrapped chain's output into messages. Dicts are handled by plucking output_messages_key (or the single key, or "output"), but after that the value must be str, BaseMessage, or list/tuple. Anything else raises this ValueError.
Source
Thrown at libs/core/langchain_core/runnables/history.py:519
# If you are wrapping a chat model directly
# The output is actually this weird generations object
if key not in output_val and "generations" in output_val:
output_val = output_val["generations"][0][0]["message"]
else:
output_val = output_val[key]
if isinstance(output_val, str):
return [AIMessage(content=output_val)]
# If value is a single message, convert to a list
if isinstance(output_val, BaseMessage):
return [output_val]
if isinstance(output_val, (list, tuple)):
return list(output_val)
msg = (
f"Expected str, BaseMessage, list[BaseMessage], or tuple[BaseMessage]. "
f"Got {output_val}."
)
raise ValueError(msg)
def _enter_history(self, value: Any, config: RunnableConfig) -> list[BaseMessage]:
hist: BaseChatMessageHistory = config["configurable"]["message_history"]
messages = hist.messages.copy()
if not self.history_messages_key:
# return all messages
input_val = (
value if not self.input_messages_key else value[self.input_messages_key]
)
messages += self._get_input_messages(input_val)
return messages
async def _aenter_history(
self, value: dict[str, Any], config: RunnableConfig
) -> list[BaseMessage]:
hist: BaseChatMessageHistory = config["configurable"]["message_history"]
messages = (await hist.aget_messages()).copy()View on GitHub (pinned to e32fa9a52e)
Solutions
- Pass output_messages_key pointing at the key that holds the str/BaseMessage/list[BaseMessage], e.g. output_messages_key="answer"
- Add a final step to the wrapped chain that maps its output to a message (e.g. itemgetter("answer") or a small RunnableLambda)
- Ensure the value at that key is a string or message objects, not arbitrary JSON
Example fix
# before
wrapped = RunnableWithMessageHistory(chain, get_history)
# chain outputs {"answer": "...", "citations": [...]} -> ValueError or wrong key
# after
wrapped = RunnableWithMessageHistory(
chain, get_history, output_messages_key="answer"
) Defensive patterns
Strategy: type-guard
Validate before calling
# dry-run the inner chain once and inspect output shape
sample = chain.invoke(sample_input)
if isinstance(sample, dict):
assert len(sample) == 1 or "output" in sample or output_messages_key, sample.keys() Type guard
from langchain_core.messages import BaseMessage
def is_message_output(v: object) -> bool:
return isinstance(v, (str, BaseMessage, list, tuple)) or isinstance(v, dict) Try / catch
try:
wrapped.invoke(payload, cfg)
except ValueError as e:
if "Expected str, BaseMessage" in str(e) and "output_val" in str(e):
wrapped2 = RunnableWithMessageHistory(
chain, get_history, output_messages_key="answer"
) Prevention
- Set output_messages_key explicitly for structured-output chains
- End the wrapped chain with a step that emits str or list[BaseMessage]
When it happens
Trigger: A wrapped chain whose output dict value at the chosen key is a non-message type (e.g. an int or nested dict), or an output that is not str/BaseMessage/list at all and not a dict; no output_messages_key configured.
Common situations: Structured-output chains returning nested JSON under a key; multi-key output dicts where the message lives under a key other than the single key or "output"; retriever-style outputs of custom types.
Related errors
- Expected a single list of messages. Got {input_val}.
- Expected str, BaseMessage, list[BaseMessage], or tuple[BaseM
- Missing keys {sorted(missing_keys)} in config['configurable'
- Expected keys {sorted(expected_keys)} do not match parameter
- The input to RunnablePassthrough.assign() must be a dict.
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/29d2b6016f692dea.
Report an issue: GitHub.