[PR #132] [CLOSED] docs: document GraphInterrupt limitation from tools and provide solution (#131) #146

Closed
opened 2026-02-16 06:17:17 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagentsjs/pull/132
Author: @suhasdeshpande
Created: 1/21/2026
Status: Closed

Base: mainHead: fix/graph-interrupt-tool-propagation


📝 Commits (1)

  • 27bf1ea docs: document GraphInterrupt limitation from tools and provide solution

📊 Changes

3 files changed (+313 additions, -0 deletions)

View changed files

.changeset/graph-interrupt-tools-documentation.md (+36 -0)
libs/deepagents/GRAPH_INTERRUPT_TOOLS.md (+146 -0)
libs/deepagents/src/middleware/graph-interrupt-tool.int.test.ts (+131 -0)

📄 Description

Summary

Addresses #131 by documenting the GraphInterrupt limitation when thrown from tools and providing the recommended solution using HITL middleware.

Problem

When a tool throws a GraphInterrupt, the error loses its interrupts property during error propagation, causing:

TypeError: undefined is not an object (evaluating 'error.interrupts.length')

Root Cause

  • LangGraph's error serialization (pregel/runner.js:171-173) only preserves {message, name} properties
  • interrupt() and GraphInterrupt are designed for graph nodes, not tools
  • When errors cross async boundaries in tool execution, custom properties are lost

Solution

Use the existing HITL middleware with interruptOn configuration:

const agent = createDeepAgent({
  tools: [myTool],
  interruptOn: {
    my_tool: true,  // Interrupt before executing tool
  },
  checkpointer: new MemorySaver(),
});

const result = await agent.invoke(input, config);

// Check for interrupts
if (result.__interrupt__) {
  // Review and approve/reject
}

// Resume with decision
await agent.invoke(
  new Command({ resume: { decisions: [{ type: "approve" }] } }),
  config
);

Changes

Added

  • libs/deepagents/GRAPH_INTERRUPT_TOOLS.md - Comprehensive documentation of the issue, root cause analysis, and recommended solutions
  • libs/deepagents/src/middleware/graph-interrupt-tool.int.test.ts - Integration test demonstrating both the issue and the proper solution
  • .changeset/graph-interrupt-tools-documentation.md - Changeset for release notes

Test Coverage

  1. Skipped test: Demonstrates the GraphInterrupt issue when thrown from tools
  2. Working test: Shows proper HITL middleware usage for tool-level approval workflows

Why This Approach

  1. No breaking changes: Uses existing HITL middleware already in deepagents
  2. Type-safe: Fully typed interrupt handling
  3. Production-ready: HITL middleware is tested and documented
  4. Flexible: Supports approve/reject/edit decisions
  5. Works with subagents: Properly propagates interrupt configuration

Upstream Issue

This is a limitation in LangGraph's error serialization. The ultimate fix requires changes upstream in LangGraph to preserve the interrupts property during error serialization.

Related

Test Plan

  • Created integration test demonstrating the recommended solution
  • Test shows proper use of HITL middleware with interruptOn
  • Test verifies interrupt handling and resume workflow
  • Documentation provides clear examples and explanations

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagentsjs/pull/132 **Author:** [@suhasdeshpande](https://github.com/suhasdeshpande) **Created:** 1/21/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/graph-interrupt-tool-propagation` --- ### 📝 Commits (1) - [`27bf1ea`](https://github.com/langchain-ai/deepagentsjs/commit/27bf1ea7fa9a43d3a81f59abc385fea67c835dec) docs: document GraphInterrupt limitation from tools and provide solution ### 📊 Changes **3 files changed** (+313 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/graph-interrupt-tools-documentation.md` (+36 -0) ➕ `libs/deepagents/GRAPH_INTERRUPT_TOOLS.md` (+146 -0) ➕ `libs/deepagents/src/middleware/graph-interrupt-tool.int.test.ts` (+131 -0) </details> ### 📄 Description ## Summary Addresses #131 by documenting the GraphInterrupt limitation when thrown from tools and providing the recommended solution using HITL middleware. ## Problem When a tool throws a `GraphInterrupt`, the error loses its `interrupts` property during error propagation, causing: ``` TypeError: undefined is not an object (evaluating 'error.interrupts.length') ``` ### Root Cause - LangGraph's error serialization (pregel/runner.js:171-173) only preserves `{message, name}` properties - `interrupt()` and `GraphInterrupt` are designed for graph **nodes**, not **tools** - When errors cross async boundaries in tool execution, custom properties are lost ## Solution Use the existing **HITL middleware** with `interruptOn` configuration: ```typescript const agent = createDeepAgent({ tools: [myTool], interruptOn: { my_tool: true, // Interrupt before executing tool }, checkpointer: new MemorySaver(), }); const result = await agent.invoke(input, config); // Check for interrupts if (result.__interrupt__) { // Review and approve/reject } // Resume with decision await agent.invoke( new Command({ resume: { decisions: [{ type: "approve" }] } }), config ); ``` ## Changes ### Added - `libs/deepagents/GRAPH_INTERRUPT_TOOLS.md` - Comprehensive documentation of the issue, root cause analysis, and recommended solutions - `libs/deepagents/src/middleware/graph-interrupt-tool.int.test.ts` - Integration test demonstrating both the issue and the proper solution - `.changeset/graph-interrupt-tools-documentation.md` - Changeset for release notes ### Test Coverage 1. **Skipped test**: Demonstrates the GraphInterrupt issue when thrown from tools 2. **Working test**: Shows proper HITL middleware usage for tool-level approval workflows ## Why This Approach 1. **No breaking changes**: Uses existing HITL middleware already in deepagents 2. **Type-safe**: Fully typed interrupt handling 3. **Production-ready**: HITL middleware is tested and documented 4. **Flexible**: Supports approve/reject/edit decisions 5. **Works with subagents**: Properly propagates interrupt configuration ## Upstream Issue This is a limitation in LangGraph's error serialization. The ultimate fix requires changes upstream in LangGraph to preserve the `interrupts` property during error serialization. ## Related - Issue #131 - LangGraph issues: #6624 (parallel tool interrupts), #6626 (interrupt ID collision) ## Test Plan - [x] Created integration test demonstrating the recommended solution - [x] Test shows proper use of HITL middleware with interruptOn - [x] Test verifies interrupt handling and resume workflow - [x] Documentation provides clear examples and explanations 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 06:17:17 -05:00
yindo closed this issue 2026-02-16 06:17:17 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#146