High severity intermediate · Fix: 2-5 min

ValueError: Node 'node_name' not found in graph

langgraph.graph.graph.ValueError (or langgraph.errors.NodeNotFoundError in v0.1.5+)

What this error means
LangGraph StateGraph encountered a reference to a node that was never added to the graph, either in add_node(), conditional edges, or end node declarations.

Stack trace

traceback
Traceback (most recent call last):
  File "agent.py", line 42, in <module>
    graph.add_edge("node_a", "node_b_typo")
  File "langgraph/graph/graph.py", line 187, in add_edge
    raise ValueError(f"Node 'node_b_typo' not found in graph")
ValueError: Node 'node_b_typo' not found in graph
QUICK FIX
Print graph.nodes.keys() before compile() to verify all referenced nodes exist; add missing nodes with graph.add_node('node_name', node_function), and use constants from langgraph.graph (START, END) instead of string literals.

Why it happens

LangGraph StateGraph enforces strict node registration: every node referenced in edges, conditional transitions, or as an END node must be explicitly registered with add_node() first. Common causes are typos in node names (case-sensitive), referencing nodes before they're added, using string node IDs that don't match the registered name, or conditional edges that route to unregistered nodes. The graph validates the DAG at runtime when edges are created or the graph is compiled.

Detection

Enable verbose logging before compiling the graph: set LangGraph's debug mode or manually iterate graph.nodes.keys() to verify all referenced nodes exist. Wrap graph.compile() in a try-except to catch validation errors before running the agent.

Causes & fixes

1

Typo in node name when adding edges (case-sensitive mismatch)

✓ Fix

Check exact spelling and case of node names. Use constants instead of string literals: NODE_NAME = 'check_input'; graph.add_edge(NODE_NAME, 'next_node') to catch typos at definition time.

2

Conditional edge routes to a node that was never added with add_node()

✓ Fix

Before add_conditional_edges(), ensure all target nodes in the condition function are registered. Add missing nodes: graph.add_node('missing_node', missing_node_func)

3

Using END or START as a node ID when they should be the constants END, START from langgraph.graph.graph

✓ Fix

Import and use the constants: from langgraph.graph import START, END; graph.add_edge(START, 'first_node'); graph.add_edge('last_node', END): not string literals.

4

Adding nodes after edges have been defined or trying to reference a node in a condition before it's registered

✓ Fix

Register all nodes first with add_node(), then add edges. Refactor: define all nodes → add all nodes → add all edges → compile.

Code: broken vs fixed

Broken - triggers the error
python
from langgraph.graph import StateGraph, START, END
from langgraph.graph.graph import END as END_CONST
from typing import TypedDict
import anthropic
import os

class AgentState(TypedDict):
    messages: list
    input: str

def check_input(state: AgentState):
    return {'messages': state['messages'] + ['input_checked']}

def process_data(state: AgentState):
    return {'messages': state['messages'] + ['processed']}

def route_next(state: AgentState):
    if len(state['messages']) > 2:
        return 'final_step'  # ❌ This node was never added to the graph
    return 'process_data'

graph = StateGraph(AgentState)
# ❌ Add nodes — but misspell 'process_data' in the edge
graph.add_node('check_input', check_input)
graph.add_node('process_dat', process_data)  # ❌ Typo: 'process_dat' not 'process_data'

graph.add_edge(START, 'check_input')
# ❌ Reference 'process_data' which doesn't exist (registered as 'process_dat')
graph.add_edge('check_input', 'process_data')
# ❌ Conditional edge references 'final_step' which was never added
graph.add_conditional_edges('check_input', route_next, {'process_data': 'process_data', 'final_step': 'final_step'})

# ❌ This will crash with: ValueError: Node 'process_data' not found in graph
compiled_graph = graph.compile()
Fixed - works correctly
python
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
import anthropic
import os

class AgentState(TypedDict):
    messages: list
    input: str

def check_input(state: AgentState):
    return {'messages': state['messages'] + ['input_checked']}

def process_data(state: AgentState):
    return {'messages': state['messages'] + ['processed']}

def final_step(state: AgentState):
    return {'messages': state['messages'] + ['final']}

def route_next(state: AgentState):
    if len(state['messages']) > 2:
        return 'final_step'  # ✅ Now this node exists
    return 'process_data'

graph = StateGraph(AgentState)
# ✅ Add ALL nodes with correct names (no typos)
graph.add_node('check_input', check_input)
graph.add_node('process_data', process_data)  # ✅ Fixed typo: 'process_data'
graph.add_node('final_step', final_step)  # ✅ Added missing node

# ✅ Use START and END constants from imports, not string literals
graph.add_edge(START, 'check_input')
graph.add_edge('check_input', 'process_data')
# ✅ All nodes referenced in conditional edges now exist
graph.add_conditional_edges('check_input', route_next, {
    'process_data': 'process_data',
    'final_step': 'final_step'
})
graph.add_edge('process_data', END)
graph.add_edge('final_step', END)

# ✅ Graph compiles successfully
compiled_graph = graph.compile()

# Verify the graph
print("Registered nodes:", list(graph.nodes.keys()))
print("Graph compiled successfully!")
Fixed three issues: corrected the typo 'process_dat' → 'process_data', added the missing 'final_step' node with graph.add_node(), and ensured all nodes referenced in conditional edges exist before calling compile().

Workaround

If you can't immediately refactor the graph structure, catch the ValueError during graph construction and print all node names: use a try-except block around graph.compile(), and in the exception handler, print graph.nodes.keys() to see what was actually registered. This reveals typos and missing nodes instantly. Then fix the add_node() calls before re-running.

Prevention

Follow this order: (1) Define all state-processing functions, (2) Create StateGraph, (3) Add ALL nodes with add_node() using a loop or explicit list to avoid typos, (4) Add edges and conditional edges, (5) Compile and test with graph.visualize() (if available) or print graph.nodes and graph.edges to validate structure before deployment. Use Python constants for node names to catch typos at import time.

Python 3.9+ · langgraph >=0.0.1 · tested on 0.1.5+
Verified 2026-04
Verify ↗

Community Notes

No notes yetBe the first to share a version-specific fix or tip.