langchain-ai/langchain · error · TypeError
RunnableBranch default must be Runnable, callable or mapping
Error message
RunnableBranch default must be Runnable, callable or mapping.
What it means
In `RunnableBranch.__init__`, the last positional argument is the default branch and must be a `Runnable`, a `Callable`, or a `Mapping` so it can be coerced via `coerce_to_runnable`. Anything else (str, int, None, list, tuple) fails this `isinstance` check and raises `TypeError`.
Source
Thrown at libs/core/langchain_core/runnables/branch.py:108
Raises:
ValueError: If the number of branches is less than `2`.
TypeError: If the default branch is not `Runnable`, `Callable` or `Mapping`.
TypeError: If a branch is not a `tuple` or `list`.
ValueError: If a branch is not of length `2`.
"""
if len(branches) < _MIN_BRANCHES:
msg = "RunnableBranch requires at least two branches"
raise ValueError(msg)
default = branches[-1]
if not isinstance(
default,
(Runnable, Callable, Mapping), # type: ignore[arg-type]
):
msg = "RunnableBranch default must be Runnable, callable or mapping."
raise TypeError(msg)
default_ = coerce_to_runnable(cast("Runnable[Input, Output]", default))
branches_ = []
for branch in branches[:-1]:
if not isinstance(branch, (tuple, list)):
msg = (
f"RunnableBranch branches must be "
f"tuples or lists, not {type(branch)}"
)
raise TypeError(msg)
if len(branch) != _MIN_BRANCHES:
msg = (
f"RunnableBranch branches must be "
f"tuples or lists of length 2, not {len(branch)}"
)View on GitHub (pinned to e32fa9a52e)
Solutions
- Wrap the final value: `RunnableBranch((cond, fn), RunnableLambda(lambda _: "default"))`.
- If the default is a sequence of steps, use a `RunnableSequence`/pipe chain: `(prompt | model | parser)`.
- If the default should be a set of parallel steps, pass a dict (Mapping) of runnables.
Example fix
# before branch = RunnableBranch((cond, fn), "fallback") # after from langchain_core.runnables import RunnableLambda branch = RunnableBranch((cond, fn), RunnableLambda(lambda _: "fallback"))
Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Callable, Mapping
from langchain_core.runnables import Runnable
ok = isinstance(default, (Runnable, Callable, Mapping))
assert ok, f"default must be Runnable/callable/mapping, got {type(default)}" Type guard
from collections.abc import Callable, Mapping
from typing import TypeGuard
from langchain_core.runnables import Runnable
def is_valid_default(d: object) -> TypeGuard[Runnable | Callable | Mapping]:
return isinstance(d, (Runnable, Callable, Mapping)) Prevention
- Always end RunnableBranch(...) with a runnable or function, never a literal.
- Wrap constants with RunnableLambda(lambda _: value).
- For multi-step defaults, use a pipe chain (RunnableSequence), not a list.
When it happens
Trigger: Ending the `RunnableBranch(...)` argument list with a non-runnable value: `RunnableBranch((cond, fn), "default")`, `RunnableBranch((cond, fn), None)`, or `RunnableBranch((cond, fn), [fn1, fn2])` (a list, not a Mapping/Runnable).
Common situations: Using a literal string as the fallback answer; passing a list of runnables expecting them to run in sequence instead of a `RunnableSequence`; a variable that is None because an optional handler was not configured; forgetting that the final argument is the default, not another condition pair.
Related errors
- RunnableBranch branches must be tuples or lists, not {type(b
- Expected a Runnable, callable or dict.Instead got an unsuppo
- RunnableBranch requires at least two branches
- RunnableBranch branches must be tuples or lists of length 2,
- unsupported operand type(s) for +: "{self.__class__.__name__
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/9f82447984ded96d.
Report an issue: GitHub.