mirror of
https://github.com/langchain-ai/deepagentsjs.git
synced 2026-07-19 08:26:01 -04:00
[GH-ISSUE #131] GraphInterrupt thrown from tool loses interrupts property during error propagation #36
Closed
opened 2026-02-16 06:16:56 -05:00 by yindo
·
3 comments
No Branch/Tag Specified
main
dependabot/npm_and_yarn/patch-deps-updates-main-c0f001c0f6
dependabot/npm_and_yarn/major-deps-updates-main-b7ceb5d816
dependabot/npm_and_yarn/minor-deps-updates-main-f52a01c0f6
dependabot/github_actions/major-deps-updates-5c183d6ffa
dependabot/github_actions/minor-deps-updates-38afab4f4d
dependabot/github_actions/patch-deps-updates-00a0d7aaea
dependabot/docker/examples/async-subagent-server/major-deps-updates-docker-4faa477378
feat/delete-backend-protocol
feat/write-file-overwrites
feat/recursive-delete-tool
corridor/fix-1119d955-1783568785287
open-swe/bump-langsmith-0-8-0
alex/initializer
cb/connectors-spec-19bb
open-swe/fs-interrupt-permissions
sydney/oolong-ptc-runners
cb/fs-permissions-interrupt-9517
hunter/swarm-oolong-eval
colifran/swarm-eval
colifran/interp-libs
colifran/workflow-poc
colifran/swarm-sub-mw-defaults
hunter/fix-ci-read-file-mime-guard
fix/filesystem-glob-suppress-permission-errors
hunter/middleware-replace-by-name
hunter/fix-node-vfs-absolute-exec-paths
colifran/lazy-skills
cb/fix-subagent-stream-same-type-isolation
fix/acp-filesystem-virtual-mode
colifran/skill-dist
colifran/skill-cli
open-swe/9065a8d9-c0c3-5c29-b106-1a195b97ddbd
colifran/permissions
colifran/repl-swarm
hunter/quickjs-pending-write-reads
colifran/swarm-in-repl
jacob/subagents
jacob/subagenttype
open-swe/7460276d-5f03-10ca-8a53-7653699f1133
colifran/swarm-tool
hunter/fix-sandbox-find-follow-symlinks
open-swe/dfd00850-86b7-5f87-2c10-3bd968b1c75e
colifran/swarm-refactor
colifran/swarm-table
colifran/swarm
open-swe/8d89ab28-9b47-3a19-427b-aacfa4c5d099
open-swe/086c3d27-2ff0-ebf5-5d74-4d35e38083c5
open-swe/23f64c62-afe9-dc40-bbe0-c86a558611b3
hunter/namespace-factories
alpha
baseten-integration
colifran/deprecate-backend-factories
colifran/agent-protocol-poc
colifran/a2a-subagents
ci/add-codeql-scanning
colifran/async-example
colifran/async-subagents-example
1.9.0-alpha.1
colifran/backend-rename
hunter/js-queue-lookahead-middleware
cb/secure-exec
cb/pass-checkpointer
colifran/multimodal-refactor-pr2
structured-output-evals
subagent-structured-output
colifran/multimodal-refactor-pr1
cb/async-agents
hunter/repl-rlm
cb/ptc-repl-network-policy
cb/ptc-repl
cb/ptc
open-swe/020b364c-2a7f-e2b2-30e0-4593befd0490
add-evals
hunter/structured-output-eval
cb/composite-fix
hunter/async-subagents
hunter/relo-evals
cb/summarization-improvements
hunter/deepbash
harbor-evals
hunter/trace-metadata
hunter/integration
cb/langsmith-sandbox
isolate-agent-skills
hunter/batch-task
fix-memory-load-state
add-e2e-test
cb/add-streaming-example
copilot/fix-partial-file-updates
copilot/fix-file-state-loss
nh/release-1.0.0
dqbd/fs-store
hunter/v1
dqbd/js
cb/createAgent-migration
cb/repo-update
palash/add-built-in-toosl
palash/skip-tools
palash/add-interrupt-config
brace/bump-langgraph
open-swe/6f37e688-42f4-458b-a26a-9de18f1c5ab8
palash/post-model-hook
palash/add-local
palash/add-post-model-hook-interrupt
palash/final-touch-ups
palash/subagent-fix
palash/add-langgraph-server
palash/update-readme
palash/change-name-to-deepagents
palash/fix-anthropic-zod-import
brace/fixes
open-swe/8357536e-2207-4292-a24d-00ea431ed4d4
open-swe/9453f008-7578-458d-bb92-e729e9fca363
deepagents@1.11.1
deepagents-acp@0.1.20
deepagents@1.11.0
deepagents-acp@0.1.19
@langchain/node-vfs@0.2.1
deepagents@1.10.8
deepagents-acp@0.1.18
deepagents@1.10.7
deepagents-acp@0.1.17
deepagents@1.10.6
deepagents-acp@0.1.16
@langchain/quickjs@0.6.0
@langchain/modal@0.1.5
@langchain/daytona@0.2.1
deepagents@1.10.5
deepagents-acp@0.1.15
@langchain/quickjs@0.5.1
deepagents@1.10.4
deepagents-acp@0.1.14
@langchain/quickjs@0.5.0
@langchain/node-vfs@0.2.0
deepagents@1.10.2
deepagents-acp@0.1.12
deepagents@1.10.1
deepagents-acp@0.1.11
@langchain/quickjs@0.4.0
deepagents@1.10.0
deepagents-acp@0.1.10
@langchain/quickjs@0.3.0
deepagents@1.9.1
deepagents-acp@0.1.9
@langchain/quickjs@0.2.6
deepagents@1.9.0
deepagents-acp@0.1.8
@langchain/sandbox-standard-tests@1.0.0
@langchain/quickjs@0.2.5
@langchain/node-vfs@0.1.4
@langchain/modal@0.1.4
deepagents@1.9.0-alpha.1
deepagents-acp@0.1.8-alpha.0
@langchain/quickjs@0.2.5-alpha.0
@langchain/node-vfs@0.1.4-alpha.0
@langchain/modal@0.1.4-alpha.0
@langchain/deno@0.2.2-alpha.0
@langchain/daytona@0.2.0-alpha.0
deepagents@1.8.8
deepagents-acp@0.1.7
@langchain/quickjs@0.2.4
deepagents@1.8.7
deepagents-acp@0.1.6
@langchain/quickjs@0.2.3
@langchain/daytona@0.2.0
deepagents@1.8.6
deepagents-acp@0.1.5
@langchain/quickjs@0.2.2
@langchain/deno@0.2.2
deepagents@1.9.0-alpha.0
deepagents-acp@0.1.5-alpha.0
@langchain/sandbox-standard-tests@1.0.0-alpha.0
@langchain/quickjs@1.0.0-alpha.0
@langchain/node-vfs@1.0.0-alpha.0
@langchain/modal@1.0.0-alpha.0
@langchain/deno@1.0.0-alpha.0
@langchain/daytona@1.0.0-alpha.0
deepagents@1.8.5
deepagents-acp@0.1.4
@langchain/quickjs@0.2.1
@langchain/node-vfs@0.1.3
deepagents@1.8.3
deepagents-acp@0.1.2
deepagents-acp@0.1.0
deepagents@1.8.1
@langchain/modal@0.1.3
deepagents@1.8.0
@langchain/sandbox-standard-tests@0.1.0
@langchain/node-vfs@0.1.2
@langchain/deno@0.2.1
@langchain/daytona@0.1.2
deepagents@1.7.6
deepagents@1.7.5
deepagents@1.7.4
@langchain/deno@0.2.0
@langchain/deno@0.1.2
deepagents@1.7.3
deepagents@1.7.2
@langchain/modal@0.1.2
deepagents@1.7.1
@langchain/node-vfs@0.1.1
@langchain/modal@0.1.1
@langchain/deno@0.1.1
@langchain/daytona@0.1.1
deepagents@1.7.0
@langchain/node-vfs@0.1.0
@langchain/modal@0.1.0
@langchain/deno@0.1.0
@langchain/daytona@0.1.0
deepagents@1.6.3
deepagents@1.6.2
deepagents@1.6.1
deepagents@1.6.0
deepagents@1.5.1
deepagents@1.5.0
deepagents@1.4.2
deepagents@1.4.1
deepagents@1.4.0
v1.3.1
v1.3.0
v1.2.0
v1.1.1
v1.1.0
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: langchain-ai/deepagentsjs#36
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @suhasdeshpande on GitHub (Jan 21, 2026).
Original GitHub issue: https://github.com/langchain-ai/deepagentsjs/issues/131
GraphInterrupt thrown from tool loses
interruptsproperty during error propagationDescription
When a tool throws a
GraphInterruptin DeepAgents, the error loses itsinterruptsproperty during propagation through the tool execution chain, causing a TypeError in LangGraph's internal_commit()function.This prevents implementing Human-in-the-Loop (HITL) approval workflows where tools need to pause execution for human review.
Environment
Problem
LangGraph's
interrupt()function is designed to be called from graph nodes. When attempting to call it (or manually construct aGraphInterrupt) from within a tool, the error propagates incorrectly:GraphInterruptwith properinterruptsarrayinterruptsproperty exists with correct structure_commit(), theinterruptsproperty is undefinedundefined is not an object (evaluating 'error.interrupts.length')Minimal Reproduction
Expected Behavior
GraphInterruptwithinterruptsarrayisInterrupted(result)or catch the errorCommand({ resume: approvalData })Actual Behavior
Console output from tool:
Then error in LangGraph:
Error location in LangGraph source (runner.js:163-164):
Analysis
The
GraphInterruptis correctly constructed with theinterruptsproperty, but somewhere in the error propagation chain (DeepAgents' tool execution or LangGraph's tool calling layer), the error gets caught and re-thrown without preserving theinterruptsarray.Evidence:
isGraphInterrupt(error)type check ✓interruptsproperty ✗Impact
This blocks implementing HITL workflows where:
Use Case
We're building a coding assistant where certain operations (spawning expensive subagents, making destructive changes) require user approval. The natural place to request approval is from within the tool that performs the action, not from a separate node.
Workarounds Attempted
1. Using
interrupt()directlyResult: Same issue - creates malformed GraphInterrupt from tool context
2. Manual GraphInterrupt construction
Result: Correctly constructed but
interruptslost during propagation (shown above)3. External state storage
Result: Works but requires side effects and race condition handling - not ideal
Questions
interrupt()from tools a supported use case?GraphInterruptproperties?GraphInterruptspecially to preserve structure?Request
Please either:
GraphInterrupt.interruptswhen thrown from tools, ORinterrupt()only works from nodes, with recommended patterns for tool-level approval workflowsAdditional Context
We've done extensive investigation and documented everything:
Happy to provide more details or collaborate on a fix!
Related
@langchain/langgraph/dist/errors.d.ts@langchain/langgraph/dist/constants.d.ts@suhasdeshpande commented on GitHub (Jan 21, 2026):
Found the proper solution - LangChain has built-in
humanInTheLoopMiddlewarethat handles this use case correctly. The middleware intercepts tool calls BEFORE execution (not during), which is the designed pattern. Closing as this was user error, not a bug.@suhasdeshpande commented on GitHub (Jan 21, 2026):
Reopening Issue: GraphInterrupt Error Propagation Bug
Why We're Reopening
We initially closed this issue believing LangChain's official
humanInTheLoopMiddlewarewould solve the problem. We were wrong.After implementing and extensively testing the official middleware, we confirmed it fails with the exact same error. This is a real, confirmed bug in DeepAgents' error propagation that affects ALL Human-in-the-Loop implementations.
The Bug (Confirmed)
When
runtime.interrupt()is called from middleware in DeepAgents, the resultingGraphInterrupterror loses itsinterruptsproperty during propagation, causing this error:What We Tested (All Failed ❌)
1. LangChain's Official
humanInTheLoopMiddleware❌Why it fails: The middleware internally calls
runtime.interrupt(), which throwsGraphInterrupt. DeepAgents strips theinterruptsproperty during error propagation.2. Custom Middleware with
wrapToolCallHook ❌Server logs prove the property exists when thrown:
3. Manual
GraphInterruptConstruction ❌Same result: Property exists when thrown, lost during propagation.
Evidence Summary
GraphInterruptcorrectly constructedinterruptsproperty exists when thrownisGraphInterrupt(error)checkinterruptsproperty preserved during propagation_commit()withinterruptsRoot Cause
DeepAgents' middleware chain catches and re-throws
GraphInterrupterrors without preserving theinterruptsproperty. The error reaches LangGraph as aGraphInterruptinstance (passes type check) but without the requiredinterruptsarray (malformed).Location: Somewhere in DeepAgents' tool execution wrapper or middleware error handling.
Impact
This bug completely blocks implementing Human-in-the-Loop approval workflows in DeepAgents:
runtime.interrupt()Working Workaround (Not Ideal)
We had to implement keyword-based detection that avoids calling
runtime.interrupt()entirely:Limitations:
Request for DeepAgents Maintainers
Please help us resolve this in one of three ways:
Option 1: Fix the Error Propagation (Preferred)
GraphInterrupt.interruptswhen catching/re-throwing in middleware chainhumanInTheLoopMiddlewareruntime.interrupt()to work from middleware hooksOption 2: Document the Limitation
Option 3: Provide Alternative Pattern
Test Environment
Files Available
We've documented everything extensively:
Happy to provide more details, test fixes, or collaborate on a solution!
Summary
This is not a usage issue - it's a real bug in DeepAgents' error handling that makes it incompatible with LangGraph's HITL pattern.
We apologize for the initial premature closure. We now have conclusive evidence that this blocks all proper HITL implementations in DeepAgents.
@suhasdeshpande commented on GitHub (Jan 21, 2026):
Additional Test Evidence
Server Logs Showing Property Loss
When
runtime.interrupt()is called from middleware, the server logs show:Stack trace:
Client receives:
The property exists when thrown but is lost during propagation through the middleware chain.
Test Files Available
All test code and reproduction scripts are available in our repository:
/apps/agents-demo/GITHUB_ISSUE.md- Full technical analysis/apps/agents-demo/ISSUE_REPRODUCTION.md- Step-by-step reproduction/apps/agents-demo/reproduce-graphinterrupt-issue.ts- Standalone reproWorking Workaround
We've implemented a keyword-based workaround that avoids
runtime.interrupt():Results: 6/6 tests passing with this workaround, but it's not the proper LangGraph HITL pattern.
Why This Matters
This bug makes DeepAgents incompatible with LangGraph's Human-in-the-Loop pattern, which is a core feature for production agentic applications. Every other LangGraph implementation supports HITL via
runtime.interrupt(), but DeepAgents cannot.We're happy to help test any fixes or provide more information!
GraphInterrupt thrown from tool loses interrupts property during error propagationto [GH-ISSUE #131] GraphInterrupt thrown from tool loses interrupts property during error propagation