Skip to content

Conversation

@rlancemartin
Copy link
Contributor

@rlancemartin rlancemartin commented Nov 6, 2025

Summary

Fixes RuntimeError when parallel subagents create multiple pending interrupts in the human-in-the-loop (HITL) workflow.

Problem

I was testing multiple sub-agents, which are used in the web-research skill. When spawning multiple subagents in parallel that require HITL approval (e.g., 3 research subagents all calling web_search), LangGraph raises:

RuntimeError: When there are multiple pending interrupts, you must specify the interrupt id when resuming.

The previous code only handled one interrupt at a time and passed a simple response dict. LangGraph requires responses for all pending interrupts to be mapped by their interrupt IDs when multiple are present.

Solution

Changes to execution.py:

  1. Collect all pending interrupts - Changed from tracking a single hitl_request to a dict pending_interrupts keyed by interrupt ID
  2. Handle each interrupt - Loop through all interrupts and collect responses (auto-approve or manual prompt)
  3. Build proper resume format:
    • Single interrupt: pass response directly {"decisions": [...]}
    • Multiple interrupts: pass dict {interrupt_id_1: {"decisions": [...]}, interrupt_id_2: {...}}

Test Plan

Tested all w/ web-research skill.

  • Test with single subagent (HITL) - should work as before
  • Test with 3 parallel subagents + --auto-approve - should auto-approve all
  • Test with 3 parallel subagents + manual HITL - should prompt for each and resume correctly

@rlancemartin rlancemartin marked this pull request as draft November 6, 2025 19:47
@rlancemartin rlancemartin marked this pull request as ready for review November 7, 2025 23:54
@eyurtsev eyurtsev self-assigned this Nov 10, 2025
Fixes RuntimeError when parallel subagents create multiple pending interrupts.
When multiple subagents call tools requiring approval simultaneously, LangGraph
needs responses for all interrupts mapped by their IDs.

Changes:
- Collect all pending interrupts in a dict keyed by interrupt_id
- Handle each interrupt (auto-approve or manual prompt)
- Build proper resume format:
  * Single interrupt: pass response directly
  * Multiple interrupts: pass {interrupt_id: response} dict
- Maintains backward compatibility with single interrupt handling

This enables parallel subagent execution with both auto-approve and manual
HITL approval workflows.
Fixes issue where interrupts created after resuming were not properly handled.
When the agent resumes from multiple interrupts and creates new interrupts,
the code now queries agent.get_state() to get ALL pending interrupts from
LangGraph's state, not just those from the current stream iteration.

This ensures proper formatting of the resume command:
- Single interrupt: pass response directly
- Multiple interrupts: pass {interrupt_id: response} dict

Previously, pending_interrupts was reset each loop iteration, causing the code
to miss interrupts that were still pending in the graph state.
@eyurtsev
Copy link
Collaborator

Pushed a rebase on top of master -- taking over the PR @rlancemartin

@eyurtsev eyurtsev merged commit 1d9fa2f into master Nov 10, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants