Back to roadmaps langgraph Course

Implementing Manual Approvals and State Updates

Once a graph is paused by an interrupt rule, it remains suspended in the checkpointer database. To continue, your application must update the state (for example, applying a human approval flag) and resume execution.


1. Resume Workflow

graph TD
    A[Graph Paused before SensitiveNode] --> B[Human reviews request on Admin UI]
    B -->|Click Approve| C[Server updates state: approvedByHuman = true]
    C -->|Resume Graph| D[SensitiveNode reads state and executes]

2. Resuming and Updating State in Node.js

Continuing from our paused compiledInterruptApp code:

// src/services/approveService.ts
import { compiledInterruptApp } from "./interruptGraph";

const runConfig = { configurable: { thread_id: "user_session_45" } };

export async function approveAndResume() {
  // 1. Fetch the current state from the checkpointer database
  const currentCheckpointState = await compiledInterruptApp.getState(runConfig);
  console.log("Current state values:", currentCheckpointState.values);

  // 2. Update the state values manually (set approval to true)
  await compiledInterruptApp.updateState(runConfig, {
    approvedByHuman: true,
  });

  // 3. Resume execution by invoking with null values (picks up from the paused node)
  const finalState = await compiledInterruptApp.invoke(null, runConfig);

  console.log("Execution resumed and completed. Final state:", finalState);
}

3. Handling Rejections

If a reviewer clicks Reject, your server can update the state with a rejection flag or bypass the sensitive node entirely. Use updateState to alter the target execution path, directing the graph to a cleanup or notification node instead.

  • Use updateState(config, { approvedByHuman: false }) to register the rejection.
  • Trigger invoke(null, config) to continue, allowing conditional edges to route the flow to an alternate exit path.
Published on Last updated: