{"record":{"id":"abbaf021f44b635f","repo":"langchain-ai/langchain","slug":"runnablebranch-branches-must-be-tuples-or-lists-of","errorCode":null,"errorMessage":"RunnableBranch branches must be tuples or lists of length 2, not {len(branch)}","messagePattern":"RunnableBranch branches must be tuples or lists of length 2, not (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/branch.py","lineNumber":127,"sourceCode":"\n        default_ = coerce_to_runnable(cast(\"Runnable[Input, Output]\", default))\n\n        branches_ = []\n\n        for branch in branches[:-1]:\n            if not isinstance(branch, (tuple, list)):\n                msg = (\n                    f\"RunnableBranch branches must be \"\n                    f\"tuples or lists, not {type(branch)}\"\n                )\n                raise TypeError(msg)\n\n            if len(branch) != _MIN_BRANCHES:\n                msg = (\n                    f\"RunnableBranch branches must be \"\n                    f\"tuples or lists of length 2, not {len(branch)}\"\n                )\n                raise ValueError(msg)\n            condition, runnable = branch\n            condition = cast(\"Runnable[Input, bool]\", coerce_to_runnable(condition))\n            runnable = coerce_to_runnable(cast(\"Runnable[Input, Output]\", runnable))\n            branches_.append((condition, runnable))\n\n        super().__init__(\n            branches=branches_,\n            default=default_,\n        )\n\n    model_config = ConfigDict(\n        arbitrary_types_allowed=True,\n    )\n\n    @classmethod\n    def is_lc_serializable(cls) -> bool:\n        \"\"\"Return `True` as this class is serializable.\"\"\"\n        return True","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/branch.py#L109-L145","documentation":"Each `(condition, runnable)` pair passed to `RunnableBranch.__init__` must have exactly 2 elements (`_MIN_BRANCHES == 2`). A tuple or list of any other length (1, 3, ...) fails the `len(branch) != _MIN_BRANCHES` check and raises `ValueError` with the actual length.","triggerScenarios":"Passing `(cond,)` (missing runnable), `(cond, fn, extra)` (extra element), or `(cond, fn, handler_kwargs)` where a config dict was mistakenly packed into the pair. Also destructuring bugs when branches are built with `zip()` of unequal lists.","commonSituations":"Trying to attach per-branch config/metadata as a third tuple element (not supported — use `.with_config()` on the runnable instead); building pairs with a loop bug that appends the wrong number of items; copy-paste leaving a trailing comma making a 1-tuple.","solutions":["Ensure each branch tuple is exactly `(condition, runnable)`.","Move per-branch options off the tuple: apply `.with_config(tags=[...])` or `.with_retry()` to the runnable inside the pair.","Log `[(type(b), len(b) if isinstance(b, (tuple, list)) else None) for b in branches]` before construction to find the malformed pair."],"exampleFix":"# before\nbranch = RunnableBranch((is_q, answer_fn, {\"tags\": [\"q\"]}), default)\n\n# after\nbranch = RunnableBranch((is_q, answer_fn.with_config(tags=[\"q\"])), default)","handlingStrategy":"validation","validationCode":"bad = [b for b in branches if not (isinstance(b, (tuple, list)) and len(b) == 2)]\nif bad:\n    raise ValueError(f\"malformed branches (need length-2 pairs): {bad!r}\")","typeGuard":"from typing import TypeGuard\n\ndef is_length2_pair(b: object) -> TypeGuard[tuple]:\n    return isinstance(b, tuple) and len(b) == 2","tryCatchPattern":null,"preventionTips":["Keep branch tuples exactly (condition, runnable).","Apply per-branch options via .with_config()/.with_retry() on the runnable, not extra tuple elements.","Watch for trailing commas that create 1-tuples."],"tags":["runnable-branch","value-error","chain-composition","langchain-core"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}