Verifying with a minimal graph
Why this matters
You need a working baseline to know whether errors come from your environment or from your logic. A minimal graph is the fastest way to verify langgraph is installed and functioning.
Explanation
A minimal graph is a langgraph with exactly one node and no branches. It receives input, does something, and returns output. Think of it as the 'Hello World' of stateful workflows. Mechanically: You define a State class to hold your data, create a StateGraph, add one node with a function, set entry/exit points using START and END, compile it, and invoke it with input. The graph runs your node function once and returns the result. When to use: Always do this first when setting up langgraph, or when you suspect your installation is broken. It eliminates the graph as a variable and isolates your actual problem.
Analogy
Like testing a single kitchen appliance before building a full kitchen: plug it in, see if it turns on, then add complexity.
Code
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
class State(TypedDict):
message: str
def process_node(state: State) -> State:
return {"message": state["message"].upper()}
graph = StateGraph(State)
graph.add_node("uppercase", process_node)
graph.add_edge(START, "uppercase")
graph.add_edge("uppercase", END)
compiled_graph = graph.compile()
result = compiled_graph.invoke({"message": "hello langgraph"})
print(result) {'message': 'HELLO LANGGRAPH'} What just happened?
You defined a <code>State</code> that holds a string message. You created a graph with one node that takes the message, converts it to uppercase, and returns it. You connected <code>START</code> to that node, and the node to <code>END</code>. You compiled the graph into an executable, then invoked it with input data. The graph ran the <code>uppercase</code> node once and returned the modified state.
Common gotcha
Forgetting to import START and END from langgraph.graph: developers often try to use string 'START' and 'END' (the old 0.1.x pattern). This will fail silently or produce cryptic errors. Always import them as objects.
Error recovery
ImportError: cannot import name 'START'KeyError on state fieldTypeError: invoke() got unexpected keyword argumentExperienced dev note
A minimal graph teaches you the shape of every langgraph you'll ever build: State → Node → Edges → Compile → Invoke. Once this runs, every larger graph is just more nodes and edges in the same pattern. Spend 30 seconds verifying it works before debugging your actual logic. Also: State is just a TypedDict: you control what fields it has. Don't overthink it. Start with one field, then add complexity.
Check your understanding
If your node function returns only {"message": "hello"} but your State has two fields (message and count), what happens when you invoke the graph?
Show answer hint
The answer requires understanding that <code>State</code> is a contract: nodes must return all fields defined in it, or the graph will raise an error. A correct answer identifies that the missing <code>count</code> field will cause a KeyError or validation error on invoke.