langchain-ai/langchain · error · ValueError
Target node {target.id} not in graph
Error message
Target node {target.id} not in graph What it means
The counterpart of the source check: `Graph.add_edge` verifies the target node's id exists in `self.nodes` after checking the source. A missing target id raises `ValueError: Target node ... not in graph`, keeping the edge list consistent with the node table.
Source
Thrown at libs/core/langchain_core/runnables/graph.py:379
Args:
source: The source node of the edge.
target: The target node of the edge.
data: Optional data associated with the edge.
conditional: Whether the edge is conditional.
Returns:
The edge that was added to the graph.
Raises:
ValueError: If the source or target node is not in the graph.
"""
if source.id not in self.nodes:
msg = f"Source node {source.id} not in graph"
raise ValueError(msg)
if target.id not in self.nodes:
msg = f"Target node {target.id} not in graph"
raise ValueError(msg)
edge = Edge(
source=source.id, target=target.id, data=data, conditional=conditional
)
self.edges.append(edge)
return edge
def extend(
self, graph: Graph, *, prefix: str = ""
) -> tuple[Node | None, Node | None]:
"""Add all nodes and edges from another graph.
Note this doesn't check for duplicates, nor does it connect the graphs.
Args:
graph: The graph to add.
prefix: The prefix to add to the node ids.
Returns:View on GitHub (pinned to e32fa9a52e)
Solutions
- Ensure the target node is added before the edge; add start/end sentinel nodes explicitly.
- After `remove_node`, also remove or rebuild edges that referenced it before adding new ones.
- Keep id types consistent (all ints or all strings), especially after (de)serializing graphs.
Example fix
# before end = Node(id="end", data=END) graph.add_edge(start, end) # end never added # after end = graph.add_node(data=END) graph.add_edge(start, end)
Defensive patterns
Strategy: validation
Validate before calling
assert target.id in graph.nodes, f"target {target.id} missing"
graph.add_edge(source, target) Prevention
- Add end/exit sentinel nodes explicitly in custom get_graph().
- Keep node id types consistent (str vs int) across the graph.
- Rebuild edges referencing removed nodes after remove_node().
When it happens
Trigger: `add_edge(a, b)` where `b` was never added, was removed by `remove_node()`, or is a new `Node` instance whose id was expected to match an existing node but does not (e.g. string vs int id `"1"` vs `1`).
Common situations: Building custom `.get_graph()` implementations that forget the end/exit node; deleting nodes with `remove_node` (which pops the node but leaves dangling edges to fix) and then re-adding edges; id-type mismatches after loading graph descriptions from JSON where keys became strings.
Related errors
- Node with id {id} already exists
- Source node {source.id} not in graph
- Canvas dimensions should be > 1
- char should be a single character
- x should be >= 0 and < number of columns
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/3b8674e83d75c016.
Report an issue: GitHub.