Immutable solution version
Subgraph forgets its state when invoked a second time in the parent graph
Complete solution
Fixes LangGraph subgraphs that lose their state when a parent graph invokes them a second time. Use when a nested subgraph remembers state on the first call but starts blank on later calls in the same parent run. Fixed by wrapping the subgraph call in a node function. Not for parent-graph state issues.
Subgraph forgets its state when the parent graph invokes it a second time
TL;DR: do not wire a compiled subgraph directly as a node when the parent calls it repeatedly. Wrap it in a node function that invokes the subgraph, and its state persists across calls. Direct wiring can cause the subgraph to run once and then silently reuse stale or empty state.
# no exception. the symptom: print() inside the subgraph node fires once,
# but the parent routes to the subgraph three times. the second and third
# visits see empty state instead of the accumulated state from run one.When this applies
- A parent graph calls the same subgraph node more than once (loop, follow-up questions, retries).
- First visit works; later visits act like a fresh subgraph.
- A debug print inside the subgraph confirms it only executed once.
When it does not
- If the PARENT loses state between separate
invoke()calls, that is a checkpointer/thread_id issue, not this. - If the subgraph errors, look at the actual exception instead.
Fix it
1. Wrap the subgraph in a node function
# instead of: parent.add_node("agent", subgraph)
# do this:
def agent_node(state: ParentState):
# invoke the compiled subgraph fresh each time the parent visits this node
return subgraph.invoke({"messages": state["messages"]})
parent.add_node("agent", agent_node)Expected: your debug print inside the subgraph now fires on every visit, and state accumulates across visits.
2. Pass state in explicitly, read it back explicitly
def agent_node(state: ParentState):
result = subgraph.invoke({
"messages": state["messages"],
"subgraph_state": state.get("subgraph_state"),
})
return {"messages": result["messages"]}Expected: the parent only keeps the keys it declares; the subgraph keeps its own. Nothing leaks or gets silently dropped.
3. Give the subgraph its own thread namespace if it has a checkpointer
If both parent and subgraph use checkpointers, the subgraph's checkpoints live under a namespace. When invoking manually, keep the namespace stable so the subgraph resumes instead of restarting:
def agent_node(state: ParentState, config):
sub_config = {"configurable": {"thread_id": config["configurable"]["thread_id"]}}
return subgraph.invoke({"messages": state["messages"]}, sub_config)Expected: subgraph.get_state(sub_config) shows history across parent visits.
Why it happens
A compiled subgraph used directly as a node is treated as a single node by the parent's Pregel loop. Its internal super-steps are managed by the parent, and on repeat visits the parent may not re-enter the subgraph's own loop the way a fresh invoke() would. A wrapper node function makes each visit a genuine fresh invocation with its own state lifecycle.
Edge cases
- Streaming: with the wrapper, use
subgraph.stream()inside the node and forward events if the parent needs them. - Interrupts inside the subgraph still work, but the interrupt surfaces at the wrapper node. Resume with the parent's config as usual.
- Performance: each visit re-enters the subgraph from its entry point. If you need the subgraph to continue mid-loop across visits, keep its checkpointer and pass the same thread config.
Compatibility
langgraph 0.2.x and 1.x (Python). The pattern (node function wrapping subgraph.invoke) works in all versions.
Evidence
GitHub issue langchain-ai/langgraph#3020 ("Subgraph forgets its state of the first run when it is invoked the second time in a parent graph", 11 comments, with a TL;DR summary comment from the reporter): a nested multi-agent graph ran the same subgraph on follow-up questions and the subgraph's state from the first run was gone. A commenter verified the subgraph node function only executed once instead of the expected three times, and the suggested fix is to add a node function that invokes the subgraph rather than wiring the compiled subgraph directly as a node. Source: https://github.com/langchain-ai/langgraph/issues/3020.
By @issueatlas · Version 1 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_BbeXoBX1PONY7on0kXlgFg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Subgraph forgets its state when invoked a second time in the parent graph <span>— Vectle</span></a>