Skip to content

Conversation

@bsbodden
Copy link
Contributor

…tributeError (#113)

Fixes #113

When Interrupt objects are serialized with orjson, they become plain dictionaries with 'value' and 'id' keys. Previously, these were not being reconstructed back to Interrupt objects during deserialization, causing AttributeError when LangGraph tried to access the .id attribute.

Added logic to _revive_if_needed() to detect serialized Interrupt objects (dicts with exactly 'value' and 'id' keys where id is a string) and reconstruct them as Interrupt objects.

The fix handles:

  • Direct Interrupt object serialization/deserialization
  • Interrupts nested in data structures (lists, dicts)
  • Interrupts in pending_sends during checkpoint resume operations

Tests added:

  • test_interrupt_serialization_roundtrip: Unit test for basic serialization
  • test_interrupt_in_pending_sends: Test for Interrupts in pending_sends structure
  • test_interrupt_resume_workflow: Integration test reproducing the issue scenario

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes issue #113 where Interrupt objects were not properly deserialized by the Redis checkpoint serializer, causing AttributeError when LangGraph attempted to access Interrupt attributes after resuming from a checkpoint.

Key Changes:

  • Added Interrupt object detection and reconstruction logic in _revive_if_needed() method
  • Interrupt objects are now identified by their serialized form (dict with value, resumable, ns, and when keys)
  • Comprehensive test suite added with unit tests for serialization roundtrip, pending_sends scenarios, and full workflow integration

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
langgraph/checkpoint/redis/jsonplus_redis.py Enhanced _revive_if_needed() to detect and reconstruct Interrupt objects from their serialized dictionary form
tests/test_issue_113_interrupt_serialization.py Added comprehensive regression tests covering direct serialization, pending_sends structure, and full workflow scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


return Interrupt(
value=obj["value"],
resumable=obj.get("resumable", False),
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Inconsistent field access: The code checks that "resumable" in obj in the detection condition (line 95), guaranteeing the field exists, but then uses obj.get("resumable", False) with a default value. This is inconsistent - if the field is guaranteed to exist by the condition, use obj["resumable"] for consistency with the value field access on line 105. Alternatively, if defaults are intentional for robustness, apply the same pattern to all fields consistently.

Suggested change
resumable=obj.get("resumable", False),
resumable=obj["resumable"],

Copilot uses AI. Check for mistakes.
…tributeError (#113)

Fixes #113

When Interrupt objects are serialized with orjson, they become plain dictionaries
with 'value', 'resumable', 'ns', and 'when' keys. Previously, these were not being
reconstructed back to Interrupt objects during deserialization, causing AttributeError
when LangGraph tried to access Interrupt attributes.

Added logic to _revive_if_needed() to detect serialized Interrupt objects
(dicts with exactly 4 keys: value, resumable, ns, when) and reconstruct them
as Interrupt objects with proper recursive handling of nested objects.

The fix handles:
- Direct Interrupt object serialization/deserialization
- Interrupts nested in data structures (lists, dicts)
- Interrupts in pending_sends during checkpoint resume operations
- Nested LangChain objects within Interrupt.value field

Tests added:
- test_interrupt_serialization_roundtrip: Unit test for basic serialization
- test_interrupt_in_pending_sends: Test for Interrupts in pending_sends structure
- test_interrupt_resume_workflow: Integration test reproducing the issue scenario
@bsbodden bsbodden merged commit c44bceb into main Nov 15, 2025
21 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.

Interrupt and invoke cannot be used simultaneously

2 participants