PREDICTIVE TREND INSIGHT
How to configure fail-safe human-in-the-loop triggers for transaction bots Illustration

How to configure fail-safe human-in-the-loop triggers for transaction bots

Direct Summary:

LangGraph's interrupt() function is the concrete mechanism for pausing a transaction bot mid-execution: calling it inside a graph node suspends the run, persists the current state, and waits indefinitely for a human decision — the graph only continues once you resume it with the human's response. This turns "require approval before large transactions" from a policy statement into an actual code-level checkpoint the agent cannot bypass.

"A goal without a plan is just a wish."

— Antoine de Saint-Exupery

Key Insights

  • The pause is real, not simulated: LangGraph persists the graph's state when interrupt() fires and genuinely waits — there's no timeout where the agent proceeds anyway if nobody responds.
  • Resuming re-runs the node from the top: when a human approves and execution resumes, LangGraph restarts the interrupted node from its beginning rather than resuming mid-line — write nodes with that in mind (idempotent where possible).
  • Put the interrupt at the decision point, not before it: call interrupt() right before the irreversible action (the actual transfer, the actual write) — checking earlier in the flow doesn't protect against logic that changes the amount afterward.

"Require human approval before large transactions" is easy to say and easy to get wrong in practice — if the check is just a prompt instruction, there's no code-level guarantee the agent actually stops. LangGraph's interrupt() makes the pause a real, structural part of the graph: the run genuinely halts, state is saved, and nothing proceeds until a human's decision comes back in.

Implementing the safeguard

1. Identify the actual irreversible action. Not "the agent decided to transfer money" — the specific line of code that calls the transfer API. That's where the interrupt belongs.

2. Call interrupt() right before that action, passing the details a human needs to decide. The value you pass is what surfaces to whoever is reviewing — include the amount, recipient, and anything else relevant to the decision.

3. Resume execution with the human's decision via Command. Only after that resume does the node continue — and since LangGraph restarts the node from its beginning, keep any pre-interrupt logic idempotent.

langgraph_transaction_approval.py
# LangGraph node that pauses for human approval before a real transfer
from langgraph.types import interrupt, Command

def process_transaction(state):
    amount = state["amount"]

    if amount > 1000:
        # Execution genuinely pauses here until a human responds
        decision = interrupt({
            "question": "Approve this transfer?",
            "amount": amount,
            "recipient": state["recipient"],
        })
        if not decision.get("approved"):
            return {"status": "rejected"}

    # Only reached after approval (or for amounts under the threshold)
    execute_transfer(amount, state["recipient"])
    return {"status": "completed"}

# Resuming after a human decision comes back:
# graph.invoke(Command(resume={"approved": True}), config=thread_config)
Approach Can the agent bypass it?
"Always ask for approval on large transfers" (prompt instruction) Potentially, under the right conditions or a model error
interrupt() before the transfer call No — execution structurally cannot proceed without a resume

The reason this matters for "fail-safe" specifically: a prompt-level instruction is a request the model usually follows; a code-level interrupt() is a checkpoint the graph runtime enforces regardless of what the model generates.

Practical Challenge

Take one action your own agent workflow can perform that would be costly if wrong, and identify the exact line where an interrupt() call should sit — right before the action executes, not earlier in the reasoning chain.

Concept Check

Why should interrupt() be called immediately before the irreversible action, rather than earlier in the agent's reasoning?
Correct! Anything that runs between an early check and the actual transfer call could alter the transaction details — the safeguard only holds if it guards the exact action being approved.
Incorrect. Try again! Hint: think about what could change between an early check and the actual execution of the action.

Sources & Further Reading

Previous Guide Dashboard Next Guide