Skip to course content
Free LangGraph course

LangGraph for Agentic Workflows

Unit 02.03: Where a run begins and how it ends

START and END are not nodes. Treating them as though they were is the source of two specific bugs.

One entry point, and at least one reachable exit

START marks where a run begins - every graph has exactly one entry. END is what a router returns when the run should stop; reaching it ends the run.

The code builds a loop that drains a list, then deliberately builds a second graph with no path to END.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END


class State(TypedDict):
    items: list
    done: list


def take(state: State):
    return {"items": state["items"][1:], "done": state["done"] + [state["items"][0]]}


def more(state: State):
    return "take" if state["items"] else END


g = StateGraph(State)
g.add_node("take", take)
g.add_edge(START, "take")
g.add_conditional_edges("take", more, {"take": "take", END: END})
app = g.compile()

print(app.invoke({"items": ["a", "b", "c"], "done": []}))

# START is not a node -- it is the entry point, and every graph has exactly one.
# END is not a node either: reaching it stops the run. A graph with no reachable
# END either loops forever or raises when it hits the recursion limit.
try:
    g2 = StateGraph(State)
    g2.add_node("take", take)
    g2.add_edge(START, "take")
    g2.add_edge("take", "take")
    g2.compile().invoke({"items": ["a"], "done": []}, {"recursion_limit": 5})
except Exception as exc:
    print(f"\nno path to END: {type(exc).__name__}")

The first graph terminates because more returns END once items is empty. The second has an edge from take back to take and nothing else, so it runs until the recursion limit and raises.

That exception is the failure mode to recognise. It does not say "your graph has no exit" - it says the recursion limit was hit, which reads like a limit that needs raising. Raising it makes the loop take longer to fail.

The mistake this prevents

The mistake is responding to a recursion-limit error by increasing the limit. It is almost always a missing termination condition, not a genuinely deep graph. Before touching the limit, find the cycle and ask what state change is supposed to break it.

Takeaway

START is the single entry point and END stops the run. Every cycle needs a reachable path to END, and a recursion-limit error is a missing termination condition until proven otherwise.