Skip to content
Back to skills

003 Name Skill 1e4cba60

ASecurity

Implement LangGraph error handling with current v1 patterns. Use when users need to classify failures, add RetryPolicy for transient issues, build LLM recovery loops with Command routing, add human-in-the-loop with interrupt()/resume, handle ToolNode errors, or choose a safe strategy between retry, recovery, and escalation.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythongobashnodedebuggingapi

Works with

  • terminal
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 003-name-skill_1e4cba60 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 003 Name Skill 1e4cba60?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 003 Name Skill 1e4cba60
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-003-name-skill-1e4cba60/badge)](https://www.skillsdirectory.com/skills/tools-only-003-name-skill-1e4cba60)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: langgraph-error-handling
description: Implement LangGraph error handling with current v1 patterns. Use when users need to classify failures, add RetryPolicy for transient issues, build LLM recovery loops with Command routing, add human-in-the-loop with interrupt()/resume, handle ToolNode errors, or choose a safe strategy between retry, recovery, and escalation.
---

# LangGraph Error Handling

## Use This Skill For
- Adding `RetryPolicy` to flaky nodes (API, DB, model/tool calls)
- Designing LLM recovery loops (`Command` + error state + retry counters)
- Adding human approval/escalation with `interrupt()` and resume
- Handling prebuilt `ToolNode` failures
- Debugging transactional failure behavior in parallel supersteps

## Strategy Selection

Use this order:

1. Transient/infrastructure issue (`429`, timeout, `5xx`, temporary DB lock) -> `RetryPolicy`
2. Recoverable by model/tool args correction -> store error in state and route back with `Command`
3. Needs user approval or missing info -> `interrupt()` + resume
4. Unknown/programming bug -> let it bubble up and debug

| Error Type | Owner | Primary Mechanism |
|---|---|---|
| Transient | System | `RetryPolicy` |
| LLM-recoverable | LLM | State update + `Command(goto=...)` |
| User-fixable | Human | `interrupt()` + `Command(resume=...)` |
| Unexpected | Developer | Raise/log/debug |

For full taxonomy, load [references/error-types.md](references/error-types.md).

## Minimal Patterns

### 1) Retry Transient Failures

```python
from langgraph.types import RetryPolicy

builder.add_node(
    "call_api",
    call_api,
    retry_policy=RetryPolicy(max_attempts=3, initial_interval=1.0),
)
```

```ts
builder.addNode("callApi", callApi, {
  retryPolicy: { maxAttempts: 3, initialInterval: 1.0 },
});
```

Notes:
- Python and JS default retry behavior differs by exception type.
- Prefer targeted `retry_on`/`retryOn` for non-transient domains.

### 2) LLM Recovery Loop

Use `MessagesState` in Python for message state.

```python
from typing import Literal
from typing_extensions import NotRequired
from langgraph.graph import MessagesState
from langgraph.types import Command

class State(MessagesState):
    error: NotRequired[str]
    retry_count: NotRequired[int]

def agent(state: State) -> Command[Literal["tool", "__end__"]]:
    if state.get("retry_count", 0) >= 3:
        return Command(goto="__end__")
    if state.get("error"):
        return Command(goto="tool")
    return Command(goto="tool")
```

```ts
import { StateGraph, Command, END } from "@langchain/langgraph";

// If a node returns Command in JS, add `ends` on addNode.
builder.addNode("agent", agentNode, { ends: ["tool", END] });
```

### 3) Human-In-The-Loop Escalation

```python
from langgraph.types import interrupt, Command

def human_review(state):
    approved = interrupt({
        "question": "Proceed?",
        "payload": state["pending_action"],
    })
    return Command(goto="execute" if approved else "cancel")

# resume
graph.invoke(Command(resume=True), config={"configurable": {"thread_id": "t-1"}})
```

```ts
import { Command, interrupt } from "@langchain/langgraph";

const approved = interrupt({ question: "Proceed?" });
// later
await graph.invoke(new Command({ resume: true }), {
  configurable: { thread_id: "t-1" },
});
```

Requirements:
- Compile with a checkpointer for interrupt flows.
- Reuse the same `thread_id` on resume.

For deep HITL patterns, load [references/human-escalation.md](references/human-escalation.md).

## ToolNode Error Handling

```python
from langgraph.prebuilt import ToolNode

tool_node = ToolNode(tools, handle_tool_errors=True)
tool_node = ToolNode(tools, handle_tool_errors="Please try again.")
tool_node = ToolNode(tools, handle_tool_errors=(ValueError, TypeError))
```

Use custom handlers when you need deterministic error shaping for model recovery.
For broader tool-recovery design, load [references/llm-recovery.md](references/llm-recovery.md).

## Critical Behavior (Do Not Skip)

1. **Supersteps are transactional**: one failing parallel branch fails the whole superstep state update.
2. **RetryPolicy retries failing branches**, not successful siblings.
3. **`interrupt()` re-runs the node on resume**: side effects before interrupt must be idempotent, or moved after interrupt / separate node.
4. **JS `Command` routing requires `ends` metadata** on `addNode(...)`.
5. **Use explicit retry limits** (`max_attempts`, plus state counters for recovery loops).

## Local Assets In This Skill

### Scripts
- `scripts/classify_error.py`: classify exception category and recommended handling
- `scripts/wrap_with_retry.py`: generate boilerplate node wrappers with retry/recovery/escalation options

Run from repo root:

```bash
uv run skills/langgraph-error-handling/scripts/classify_error.py TimeoutError --verbose
uv run skills/langgraph-error-handling/scripts/wrap_with_retry.py call_llm --with-llm-recovery
```

### Examples
- `assets/examples/retry-example/`: retry + recovery loop (Python and JS)
- `assets/examples/human-loop-example/`: interrupt/resume approval flow (Python and JS)

## Load References On Demand

- `references/error-types.md`: error taxonomy and classification rules
- `references/retry-strategies.md`: retry tuning, backoff, circuit-breaker-style patterns
- `references/llm-recovery.md`: recovery-loop and ToolNode strategies
- `references/human-escalation.md`: human approval, interrupts, and escalation patterns

## Common Failure Modes

| Symptom | Root Cause | Fix |
|---|---|---|
| `interrupt()` fails at runtime | no checkpointer | compile with checkpointer |
| Resume starts new run | different `thread_id` | reuse same `thread_id` |
| JS Command route not taken | missing `ends` | add `ends` to `addNode` |
| Infinite loop | no termination counter/condition | add retry counter + terminal branch |
| Retry never triggers | exception excluded by retry filter | set explicit `retry_on`/`retryOn` |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.