{"record":{"id":"80975427f79d21c4","repo":"langchain-ai/langchain","slug":"runnable-dep-has-no-first-node","errorCode":null,"errorMessage":"Runnable {dep} has no first node","messagePattern":"Runnable (.+?) has no first node","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/base.py","lineNumber":5106,"sourceCode":"    def get_graph(self, config: RunnableConfig | None = None) -> Graph:\n        if deps := self.deps:\n            # Import locally to prevent circular import\n            from langchain_core.runnables.graph import Graph  # noqa: PLC0415\n\n            graph = Graph()\n            input_node = graph.add_node(self.get_input_schema(config))\n            output_node = graph.add_node(self.get_output_schema(config))\n            for dep in deps:\n                dep_graph = dep.get_graph()\n                dep_graph.trim_first_node()\n                dep_graph.trim_last_node()\n                if not dep_graph:\n                    graph.add_edge(input_node, output_node)\n                else:\n                    dep_first_node, dep_last_node = graph.extend(dep_graph)\n                    if not dep_first_node:\n                        msg = f\"Runnable {dep} has no first node\"\n                        raise ValueError(msg)\n                    if not dep_last_node:\n                        msg = f\"Runnable {dep} has no last node\"\n                        raise ValueError(msg)\n                    graph.add_edge(input_node, dep_first_node)\n                    graph.add_edge(dep_last_node, output_node)\n        else:\n            graph = super().get_graph(config)\n\n        return graph\n\n    @override\n    def __eq__(self, other: object) -> bool:\n        if isinstance(other, RunnableLambda):\n            if hasattr(self, \"func\") and hasattr(other, \"func\"):\n                return self.func == other.func\n            if hasattr(self, \"afunc\") and hasattr(other, \"afunc\"):\n                return self.afunc == other.afunc\n            return False","sourceCodeStart":5088,"sourceCodeEnd":5124,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/base.py#L5088-L5124","documentation":"`RunnableEachBase.get_graph()` builds a graph by trimming each dependency runnable's sub-graph and extending it between input/output schema nodes. If a dependency's trimmed graph extends without producing a first node, a `ValueError` is raised — the fan-in/fan-out structure of `RunnableEach` cannot be drawn. Root cause is a dependency with an empty or malformed `get_graph()`.","triggerScenarios":"`my_runnable.map()` (which produces a `RunnableEach`) where the bound runnable or a dependency has a broken/empty `get_graph()`, then calling `.get_graph()` or graph visualization on the mapped runnable.","commonSituations":"Custom `Runnable` subclasses used with `.map()` without a proper `get_graph` override; visualizing batch-processing pipelines; third-party runnables with graph-API incompatibilities.","solutions":["Fix the dependency's `get_graph()` to return a graph containing at least one node.","Wrap the mapped runnable's inner function in `RunnableLambda` before `.map()`.","Check each dependency: `assert dep.get_graph().first_node() is not None`.","Skip graph rendering for exotic runnables, or register a simple proxy node for them."],"exampleFix":"// before\nbatch = my_custom_runnable.map()  # custom get_graph is empty\nbatch.get_graph().draw_ascii()  # ValueError\n\n// after\nbatch = RunnableLambda(my_fn).map()\nbatch.get_graph().draw_ascii()  # ok","handlingStrategy":"validation","validationCode":"def deps_stitchable(mapped) -> bool:\n    for dep in getattr(mapped, 'deps', []):\n        g = dep.get_graph()\n        g.trim_first_node()\n        g.trim_last_node()\n        if g.nodes:\n            return True\n    return len(getattr(mapped, 'deps', [])) == 0","typeGuard":null,"tryCatchPattern":"try:\n    g = mapped.get_graph()\nexcept ValueError as e:\n    if 'has no first node' in str(e):\n        # rebuild the mapped runnable around a RunnableLambda\n        raise\n    raise","preventionTips":["Only call .map() on runnables with well-formed get_graph().","Wrap custom runnables in RunnableLambda before .map().","Unit-test get_graph() for any runnable used with .map()."],"tags":["runnable","runnable-each","map","graph","get-graph"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}