Live survey304 models · 14 providers · 22,792 auditsAudited grill-with-docs · SAFE →What changedHow we verifyllms.txt

Agent skill · Audited from source

langgraph-human-in-the-loop

skill · langchain-ai/langchain-skillsMIT licenceAudited 31 Oct 2026 · source a78b2e2257e3

★ 1,318pushed 1 day ago
!CAUTIONGrade B · 89/100 · 1 finding · a78b2e2
1,318repo stars · whole langchain-ai/langchain-skills

Is it safe? With care — CAUTION, grade B (89/100). We read this skill's source at commit a78b2e2257e3 and found no filesystem, network or shell access and no hard-coded secrets. The audit raised 1 finding, 0 critical or high. What it does: INVOKE THIS SKILL when implementing human-in-the-loop patterns, pausing for approval, or handling errors in LangGraph. Covers interrupt(), Command(resume=...), approval/validation workflows, and the 4-tier error…

Ask an AI about this pageGChatGPTCClaudePPerplexityGeGeminiXGrok
More
Cite

Cite this page

ModelsAtlas. “langgraph-human-in-the-loop (langchain-ai/langchain-skills)”. Retrieved 31 Oct 2026. https://modelsatlas.com/skills/langchain-ai/langgraph-human-in-the-loop

Trust audit

Audit 0.4.1 · source read 31 Oct 2026

Trust score89/100!CAUTION B
0 critical0 high1 medium0 low0 info

CAUTION means the audit found things worth knowing before you trust this skill. Grade B is shared by 16,667 of 17,602 audited skills.

What the source does

  • FilesystemNone observedNo reads or writes in the source
  • NetworkNone observedNo outbound calls in the source
  • ShellNone observedNo commands run in the source
  • DependenciesPinnedNothing floats
  • SecretsNone foundNo keys in source

Five audit layers

LayerWhat we checkResultFindings
L0 ProvenanceRepo owner, licence, archive status, activityPASS0
L1 Static sourceSecrets, path traversal, supply chain, hidden codeNA0
L2 InstructionsPrompt injection, authority framing, hidden directivesWARN1
L3 InventoryThe files and declarations match the sourcePASS0
L4 SandboxRun in isolation and watch behaviourSKIPPED why0

Gates applied: no behavioural pass.

Findings (1)

MEDIUMPrivilege escalation / persistencereview.unsafe_action · SKILL.md
F-06 Privilege escalation / persistenceCWE-269 · CWE-250Layer L2
db.create_audit_log(user_id=state["user_id"], action="approved")
Why
The package directs that non-idempotent database side effects run after interrupts without requiring user confirmation for each occurrence.
Fix
rewrite it so the instruction says plainly what it does, and asks the user before it acts

Audit 0.4.1 · source sha a78b2e2257e3 · 31 Oct 2026Report an issue or request a re-scan

Provenance

Who published it, and what the verdict is pinned to

  • Publisherlangchain-ai GitHub organizationOwner of the repository this skill is read from
  • Source folderlangchain-ai/langchain-skills/config/skills/langgraph-human-in-the-loopThe exact folder we audited
  • LicenceMITAs the repository states it
  • Commit pinned for this verdicta78b2e2257e3A new audit runs when the source changes
  • Repository statusNot archivedLast push 1 day ago
  • Sandboxed runNot runSkills are read, not executed; layer L4 is skipped

What it tells the agent

Full source on GitHub ↗

Its description: INVOKE THIS SKILL when implementing human-in-the-loop patterns, pausing for approval, or handling errors in LangGraph. Covers interrupt(), Command(resume=...), approval/validation workflows, and the 4-tier error…

---
name: langgraph-human-in-the-loop
description: "INVOKE THIS SKILL when implementing human-in-the-loop patterns, pausing for approval, or handling errors in LangGraph. Covers interrupt(), Command(resume=...), approval/validation workflows, and the 4-tier error handling strategy."
---

<overview>
LangGraph's human-in-the-loop patterns let you pause graph execution, surface data to users, and resume with their input:

- **`interrupt(value)`** — pauses execution, surfaces a value to the caller
- **`Command(resume=value)`** — resumes execution, providing the value back to `interrupt()`
- **Checkpointer** — required to save state while paused
- **Thread ID** — required to identify which paused execution to resume
</overview>

---

## Requirements

Three things are required for interrupts to work:

1. **Checkpointer** — compile with `checkpointer=InMemorySaver()` (dev) or `PostgresSaver` (prod)
2. **Thread ID** — pass `{"configurable": {"thread_id": "..."}}` to every `invoke`/`stream` call
3. **JSON-serializable payload** — the value passed to `interrupt()` must be JSON-serializable

---

## Basic Interrupt + Resume

`interrupt(value)` pauses the graph. The value surfaces in the result under `__interrupt__`. `Command(resume=value)` resumes — the resume value becomes the return value of `interrupt()`.

**Critical**: when the graph resumes, the node restarts from the **beginning** — all code before `interrupt()` re-runs.

<ex-basic-interrupt-resume>
<python>
Pause execution for human review and resume with Command.

```python
from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict

class State(TypedDict):
    approved: bool

def approval_node(state: State):
    # Pause and ask for approval
    approved = interrupt("Do you approve this action?")
    # When resumed, Command(resume=...) returns that value here
    return {"approved": approved}

checkpointer = InMemorySaver()
graph = (
    StateGraph(State)
    .add_node("approval", approval_node)
    .add_edge(START, "approval")
    .add_edge("approval", END)
    .compile(checkpointer=checkpointer)
)

config = {"configurable": {"thread_id": "thread-1"}}

# Initial run — hits interrupt and pauses
result = graph.invoke({"approved": False}, config)
print(result["__interrupt__"])
# [Interrupt(value='Do you approve this action?')]

# Resume with the human's response
result = graph.invoke(Command(resume=True), config)
print(result["approved"])  # True
```
</python>
<typescript>
Pause execution for human review and resume with Command.

```typescript
import { interrupt, Command, MemorySaver, StateGraph, StateSchema, START, END } from "@langchain/langgraph";
import { z } from "zod";

const State = new StateSchema({
  approved: z.boolean().default(false),
});

const approvalNode = async (state: typeof State.State) => {
  // Pause and ask for approval
  const approved = interrupt("Do you approve this action?");
  // When resumed, Command({ resume }) returns that value here
  return { approved };
};

const checkpointer = new MemorySaver();
const graph = new StateGraph(State)
  .addNode("approval", approvalNode)
  .addEdge(START, "approval")
  .addEdge("approval", END)
  .compile({ checkpointer });

const config = { configurable: { thread_id: "thread-1" } };

// Initial run — hits interrupt and pauses
let result = await graph.invoke({ approved: false }, config);
console.log(result.__interrupt__);
// [{ value: 'Do you approve this action?', ... }]

// Resume with the human's response
result = await graph.invoke(new Command({ resume: true }), config);
console.log(result.approved);  // true
```
</typescript>
</ex-basic-interrupt-resume>

---

## Approval Workflow

A common pattern: interrupt to show a draft, then route based on the human's decision.

<ex-approval-workflow>
<python>
Interrupt for human review, then route to send or end based on the decision.

```python
from langgraph.types import interrupt, Command
from langgraph.graph import StateGraph, START, END
from typing import Literal
from typing_extensions import TypedDict

class EmailAgentState(TypedDict):
    email_content: str
    draft_response: str
    classification: dict

def human_review(state: EmailAgentState) -> Command[Literal["send_reply", "__end__"]]:
    """Pause for human review using interrupt and route based on decision."""
    classification = state.get("classification", {})

    # interrupt() must come first — any code before it will re-run on resume
    human_decision = interrupt({
        "email_id": state.get("email_content", ""),
        "draft_response": state.get("draft_response", ""),
        "urgency": classification.get("urgency"),
        "action": "Please review and approve/edit this response"
    })

    # Process the human's decision
    if human_decision.get("approved"):
        return Command(
            update={"draft_response": human_decision.get("edited_response", state.get("draft_response", ""))},
            goto="send_reply"
        )
    else:
        # Rejection — human will handle directly
        return Command(update={}, goto=END)
```
</python>
<typescript>
Interrupt for human review, then route to send or end based on the decision.

```typescript
import { interrupt, Command, END, GraphNode } from "@langchain/langgraph";

const humanReview: GraphNode<typeof EmailAgentState> = async (state) => {
  const classification = state.classification!;

  // interrupt() must come first — any code before it will re-run on resume
  const humanDecision = interrupt({
    emailId: state.emailContent,
    draftResponse: state.responseText,
    urgency: classification.urgency,
    action: "Please review and approve/edit this response",
  });

  // Process the human's decision
  if (humanDecision.approved) {
    return new Command({
      update: { responseText: humanDecision.editedResponse || state.responseText },
      goto: "sendReply",
   

Excerpt, first 6,000 characters of SKILL.md, verbatim from the audited commit. It is text from someone else’s repository, quoted so you can judge it before your agent reads it.

Install

Pinned to the audited commit a78b2e2

Download folder ↗
git clone https://github.com/langchain-ai/langchain-skills
git -C langchain-skills checkout a78b2e2257e3

The author documents no install command, so this uses the repository directly. Our verdict covers commit a78b2e2257e3 only.

Works in

The author has not said which agents this skill supports, and we have not tested it in any.

Audit history

Every audit, every source change

  1. !CAUTION B 89 / 100

    first audit · source a78b2e2257e3

README badge

For maintainers · shows the latest audit

ModelsAtlas: CAUTION BMODELSATLASCAUTION · B
[![ModelsAtlas: CAUTION B](https://modelsatlas.com/skills/langchain-ai/langgraph-human-in-the-loop/badge.svg)](https://modelsatlas.com/skills/langchain-ai/langgraph-human-in-the-loop/)

The badge shows our verdict and grade for this skill, and links back to this page. It changes when the audit does.

Similar skills

Add this badge to your README

[![ModelsAtlas: CAUTION B](https://modelsatlas.com/skills/langchain-ai/langgraph-human-in-the-loop/badge.svg)](https://modelsatlas.com/skills/langchain-ai/langgraph-human-in-the-loop/)

Questions about langgraph-human-in-the-loop

Is langgraph-human-in-the-loop safe to install?
With care. The audit graded it B (89/100) and found 1 thing worth knowing before you trust this skill, listed below with the exact line each was found on.
What can langgraph-human-in-the-loop access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (a78b2e2257e3), read on 2026-10-31. The repository is watched, and a new audit runs when it changes — this is the first audit.

Sources

Spotted something wrong? Report a correction · Methodology

Keep going in your AI

Opens with this page as the source. We add nothing else to the prompt.