AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Langchain 1.4.0: After_model Middleware With Jump_to='Tools' Bypasses HITL Pending_tool_calls Gate

In langchain 1.4.0, the HumanInTheLoopMiddleware records pending tool calls before interrupting. Any other after_model middleware that returns the documented {"jump_to": "tools"} outcome routes the graph directly to the tool node, skipping the HITL middleware entirely. This allows previously rejected (or not-yet-reviewed) tool calls to execute with user authority, silently defeating human-in-the-loop approval.

criticalConfidence 95%LangchainAffected V1.4.0

Origin Analysis

The graph routing in libs/langchain_v1/langchain/agents/factory.py short-circuits jump_to="tools" directly to the ToolNode without re-entering the HumanInTheLoopMiddleware or re-checking pending_tool_calls. The HITL gate only applies during the normal model→HITL→tools path; a jump_to from another middleware bypasses this invariant, leading to execution of rejected tool calls.
1. Create an agent with HumanInTheLoopMiddleware (interrupt_on={"unsafe_tool": {"allowed_decisions": ["approve", "reject"]}}) and an additional AfterModelMiddleware that returns {"jump_to": "tools"} when the model emits tool calls.\n2. Run the agent: the model proposes calling unsafe_tool; HITL interrupts.\n3. Resume the conversation with a Command that rejects the tool call (decision='reject').\n4. Observe that the unsafe_tool executes and writes its marker file, despite the rejection.\nControl run without the jump middleware does not execute the tool.

Fixing Code Block

Edge Case Audit

This guard relies on pending_tool_calls being correctly populated and cleaned. If the HITL middleware is not used, pending_tool_calls may be absent or stale, causing no effect. In concurrent or multi-threaded runs with shared state, pending_tool_calls may not be thread-safe, leading to race conditions. Rolling back this fix should be done only after reverting to a version without additional jump_to middlewares. Upgrade from 1.4.0 to a patched version may require re-testing all middleware combinations to ensure no legitimate jump_to flows are blocked.

Ecosystem Topology