1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson →
Review and edit an action before it runs
Reviewing and editing is a human-in-the-loop pattern: the graph pauses with a proposed action, and the human resumes with a corrected value that the graph then uses.
Last updated: 27 Sep, 2026 · LangGraph 1.2
The interrupt lesson paused for a yes or no. Often a person wants to change the action, not only approve it, so the value they send back on resume becomes the one the graph uses.
Pausing with a proposed action
The node calls interrupt with the draft it proposes. Whatever the human returns on resume comes back as the value of that call.
def review(state):
approved = interrupt({"proposed": state["draft"]}) # pause, show the draft
return {"sent": approved} # use the returned value, edited or notResuming with an edited value
Run once to hit the pause, then resume with Command(resume=...) carrying the corrected value. A checkpointer is required so the run can wait.
graph.invoke({"draft": "Refund $100", "sent": ""}, cfg) # stops at the pause
out = graph.invoke(Command(resume="Refund $50"), cfg) # human edits it
print(out["sent"])Editing a refund before it is sent
The whole program in one file.
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import InMemorySaver
class State(TypedDict):
draft: str
sent: str
def review(state):
approved = interrupt({"proposed": state["draft"]}) # pause and show the draft
return {"sent": approved} # use what the human returns
b = StateGraph(State)
b.add_node("review", review)
b.add_edge(START, "review")
b.add_edge("review", END)
graph = b.compile(checkpointer=InMemorySaver())
cfg = {"configurable": {"thread_id": "1"}}
graph.invoke({"draft": "Refund $100", "sent": ""}, cfg) # runs up to the pause
out = graph.invoke(Command(resume="Refund $50"), cfg) # human edits, then resume
print(out["sent"])What the human changed
- The run paused at
interruptwith the proposed draft, "Refund $100". - The human resumed with "Refund $50", so
interruptreturned that value. - The node wrote the edited value to
sent, so the graph acted on the correction.
Approve only vs review and edit
| Approve or reject | Review and edit | |
|---|---|---|
| Resume value | True or False | The corrected value itself |
| The human can | Let it run or stop it | Change what runs |
| Use for | A yes or no gate | Fixing an amount, a recipient, a query |
When to let a human edit
- A money amount, a recipient or a destructive action a person should adjust.
- A tool call whose arguments a reviewer wants to correct before it runs.
- A draft reply a human tidies before it is sent.
Watch out. The node must use the returned value, not the original. If it ignores what
interrupt returns, the edit is lost and the human's change does nothing.Related
- Previous: interrupt: pause for a human
- Next: Streaming: watch a run happen
Try it yourself
- Resume with the unchanged draft and confirm it sends "Refund $100".
- Return a dict from the human and read one field of it in the node.
- Remove the checkpointer and read the error about needing one to pause.
You understood something today that you didn't yesterday.