[PR #6057] Fix human-in-the-loop interrupts without checkpointer #4807

Closed
opened 2026-02-20 17:50:46 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langchain-ai/langgraph/pull/6057

State: closed
Merged: No


Fixes #6053

Problem

Human-in-the-loop interrupts using the interrupt() function were not working when graphs were compiled without a checkpointer and invoked without a thread_id. The interrupt key was missing from invoke() results, causing tool calls to proceed normally instead of triggering the review panel.

Root Cause

In the _suppress_interrupt() method in libs/langgraph/langgraph/pregel/_loop.py, interrupt information was not being included in the final output for invoke mode when no checkpointer was present.

Solution

Modified the _suppress_interrupt() method to:

  1. Properly distinguish interrupt types: Static interrupts (interrupt_before/interrupt_after) vs dynamic interrupts (interrupt() function)
  2. Emit proper stream chunks: For both interrupt types in stream mode
  3. Include interrupt data in final output: Ensure interrupt is present in invoke() results even without checkpointer
  4. Handle different output formats: Support both dict and non-dict outputs

Testing

  • Dynamic interrupts now work without checkpointer
  • No regression in existing functionality with checkpointer
  • Normal execution without interrupts unaffected
  • Stream mode continues to work correctly

Files Changed

  • libs/langgraph/langgraph/pregel/_loop.py: Core fix in _suppress_interrupt() method
  • examples/human_in_the_loop/minimal_reproduce_bug.py: Example demonstrating the original issue
  • examples/human_in_the_loop/fixed_human_loop.py: Example showing the fix

This enables human-in-the-loop functionality to work correctly even without a checkpointer, making it easier for developers to implement review workflows.

**Original Pull Request:** https://github.com/langchain-ai/langgraph/pull/6057 **State:** closed **Merged:** No --- Fixes #6053 ## Problem Human-in-the-loop interrupts using the interrupt() function were not working when graphs were compiled without a checkpointer and invoked without a thread_id. The __interrupt__ key was missing from invoke() results, causing tool calls to proceed normally instead of triggering the review panel. ## Root Cause In the _suppress_interrupt() method in libs/langgraph/langgraph/pregel/_loop.py, interrupt information was not being included in the final output for invoke mode when no checkpointer was present. ## Solution Modified the _suppress_interrupt() method to: 1. **Properly distinguish interrupt types**: Static interrupts (interrupt_before/interrupt_after) vs dynamic interrupts (interrupt() function) 2. **Emit proper stream chunks**: For both interrupt types in stream mode 3. **Include interrupt data in final output**: Ensure __interrupt__ is present in invoke() results even without checkpointer 4. **Handle different output formats**: Support both dict and non-dict outputs ## Testing - Dynamic interrupts now work without checkpointer - No regression in existing functionality with checkpointer - Normal execution without interrupts unaffected - Stream mode continues to work correctly ## Files Changed - libs/langgraph/langgraph/pregel/_loop.py: Core fix in _suppress_interrupt() method - examples/human_in_the_loop/minimal_reproduce_bug.py: Example demonstrating the original issue - examples/human_in_the_loop/fixed_human_loop.py: Example showing the fix This enables human-in-the-loop functionality to work correctly even without a checkpointer, making it easier for developers to implement review workflows.
yindo added the pull-request label 2026-02-20 17:50:46 -05:00
yindo closed this issue 2026-02-20 17:50:46 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#4807