If an interrupt already exists, use the command to trigger a jump and then trigger another interrupt. #1081

Open
opened 2026-02-20 17:43:00 -05:00 by yindo · 0 comments
Owner

Originally created by @li-qingchen on GitHub (Dec 4, 2025).

Checked other resources

  • This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • I added a clear and detailed title that summarizes the issue.
  • I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.

Example Code

from pprint import pprint

from langchain_core.language_models import FakeListChatModel
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import interrupt, Command


class State(MessagesState):
    interrupt: int
    chat: int


def payment_interrupt_node(state: State):
    message_list = []
    fake_message = FakeListChatModel(responses=["Order creation successful!"]).invoke("")
    message_list.append(fake_message)

    payload = interrupt("Payment Link...")

    data = payload.get("data")  # payment data
    message = payload.get("message")  # human message

    if data:
        message_list.append({"role": "ai", "content": data})
        return Command(
            goto="delivery",
            update={
                "interrupt": state.get("interrupt", 0) + 1,
                "messages": message_list
            }
        )

    if message:
        message_list.append({"role": "human", "content": message})
        if message == "normal conversation":
            message_list.append({"role": "ai", "content": "relpy message"})
            return {
                "chat": state.get("chat", 0) + 1,
                "messages": message_list
            }

        message_list.append({"role": "ai", "content": "some interrupt"})
        return Command(
            goto="another_interrupt_node",
            update={
                "chat": state.get("chat", 0) + 1,
                "messages": message_list
            }
        )

    # Error
    message_list.append({"role": "ai", "content": "Error!!!"})
    return {"messages": message_list}


def delivery(state: State):
    return {"messages": [{"role": "ai", "content": "Delivery message."}]}


def another_interrupt_node(state: State):
    # ...
    payload = interrupt("Send another interrupt(for some reason)")
    return {"messages": [
        {"role": "human", "content": str(payload)},
        {"role": "ai", "content": "never mind"},
    ]}


# build graph
graph = StateGraph(State)

graph.add_node(payment_interrupt_node)
graph.add_node(delivery)
graph.add_node(another_interrupt_node)

graph.add_edge(START, "payment_interrupt_node")
graph.add_edge("another_interrupt_node", END)
graph.add_edge("delivery", END)

checkpointer = InMemorySaver()
graph = graph.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "1"}}

# create order and need payment
for model, value in graph.stream(
        {"messages": [{"role": "user", "content": "buy something"}]},
        stream_mode=["messages", "updates", "checkpoints"],
        config=config,
        debug=True,
):
    pass
    # print("model: ", model)
    # print("value: ")
    # pprint(value, sort_dicts=False, width=40)

print("+" * 100)

################################ Case: Pay Now ##########################################
# #
# # There is no problem with this case, so let's ignore it
# for model, value in graph.stream(
#         Command(resume={"data": "pay success"}),
#         stream_mode=["messages", "updates", "checkpoints"],
#         config=config,
#         debug=True,
# ):
#     pass
#     # print("model: ", model)
#     # print("value: ")
#     # pprint(value, sort_dicts=False, width=40)


################################ Case: Pay Later (without interrupt) ##########################################
# for model, value in graph.stream(
#         Command(resume={"message": "normal conversation"}),
#         stream_mode=["messages", "updates", "checkpoints"],
#         config=config,
#         debug=True,
# ):
#     pass
#     # print("model: ", model)
#     # print("value: ")
#     # pprint(value, sort_dicts=False, width=40)
#
# print("+" * 100)
#
# # then the user paid for the order
# for model, value in graph.stream(
#         Command(
#             goto="payment_interrupt_node",
#             resume={"data": "30$"}
#         ),
#         stream_mode=["messages", "updates", "checkpoints"],
#         config=config,
#         debug=True,
# ):
#     pass
#     # print("model: ", model)
#     # print("value: ")
#     # pprint(value, sort_dicts=False, width=40)


################################ Case: Pay Later (with interrupt) ##########################################
for model, value in graph.stream(
        Command(resume={"message": "ask some information"}),
        stream_mode=["messages", "updates", "checkpoints"],
        config=config,
        debug=True,
):
    pass
    # print("model: ", model)
    # print("value: ")
    # pprint(value, sort_dicts=False, width=40)

print("+" * 100)

# there have an interrupt
# at same time
# then the user paid for the order
for model, value in graph.stream(
        Command(
            goto="payment_interrupt_node",
            resume={"data": "30$"}
        ),
        stream_mode=["checkpoints"],
        config=config,
        debug=True,
):
    # pass
    print("model: ", model)
    print("value: ")
    pprint(value, sort_dicts=False, width=40)

print("+" * 100)

# here not go to the delivery node, i don't know why
state = graph.get_state(config=config)
print("state: ", state)

Error Message and Stack Trace (if applicable)

[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')]}
[updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='c0fb60800beeed446c93ad2b8bf6664a'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')], '__interrupt__': (Interrupt(value='Payment Link...', id='c0fb60800beeed446c93ad2b8bf6664a'),)}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')]}
[updates] {'payment_interrupt_node': {'chat': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), {'role': 'human', 'content': 'ask some information'}, {'role': 'ai', 'content': 'some interrupt'}]}}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1}
[updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1, '__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),)}

# CASE_1: another_interrupt_node
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1}
model:  checkpoints
value: 
{'config': {'configurable': {'checkpoint_ns': '',
                             'thread_id': '1',
                             'checkpoint_id': '1f0d0de5-3edf-6edc-8001-cfb96672d6aa'}},
 'parent_config': {'configurable': {'thread_id': '1',
                                    'checkpoint_ns': '',
                                    'checkpoint_id': '1f0d0de5-3ed1-6760-8000-d80192f02970'}},
 'values': {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'),
                         AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'),
                         HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'),
                         AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')],
            'chat': 1},
 'metadata': {'source': 'loop',
              'step': 1,
              'parents': {}},
 'next': ['another_interrupt_node',
          'payment_interrupt_node'],
 'tasks': [{'id': '082e1f9e-955b-fd99-852f-f6bb62d3c174',
            'name': 'another_interrupt_node',
            'interrupts': ({'value': 'Send '
                                     'another '
                                     'interrupt(for '
                                     'some '
                                     'reason)',
                            'id': 'b51ab1eac2e8c57092a14fc1bce1e4b5'},),
            'state': None},
           {'id': '36f1a7d2-f471-a97b-536c-a54d7e2862b2',
            'name': 'payment_interrupt_node',
            'interrupts': (),
            'state': None}]}
[updates] {'another_interrupt_node': {'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}}
[updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1, '__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b'), HumanMessage(content="{'data': '30$'}", additional_kwargs={}, response_metadata={}, id='1a5a6f70-e3f0-4145-a3ac-5627616ecaa4'), AIMessage(content='never mind', additional_kwargs={}, response_metadata={}, id='2605030a-4040-4fbf-aa06-6497ef5123ae')], 'chat': 1}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
state:  StateSnapshot(values={'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b'), HumanMessage(content="{'data': '30$'}", additional_kwargs={}, response_metadata={}, id='180dc6ad-0733-4c92-92a2-cec63db41c42'), AIMessage(content='never mind', additional_kwargs={}, response_metadata={}, id='11da48f9-fe67-4b0f-ae4c-7a5db0bf4263')], 'chat': 1}, next=(), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d0de5-3edf-6edc-8001-cfb96672d6aa'}}, metadata={'source': 'loop', 'step': 1, 'parents': {}}, created_at='2025-12-04T06:56:15.790857+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d0de5-3ed1-6760-8000-d80192f02970'}}, tasks=(PregelTask(id='082e1f9e-955b-fd99-852f-f6bb62d3c174', name='another_interrupt_node', path=('__pregel_pull', 'another_interrupt_node'), error=None, interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),), state=None, result={'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}),), interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),))

# CASE_2: payment_interrupt_node
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1}
model:  checkpoints
value: 
{'config': {'configurable': {'checkpoint_ns': '',
                             'thread_id': '1',
                             'checkpoint_id': '1f0d17d6-c2fc-6f1c-8001-ed3f54d18cdc'}},
 'parent_config': {'configurable': {'thread_id': '1',
                                    'checkpoint_ns': '',
                                    'checkpoint_id': '1f0d17d6-c2f4-6146-8000-26fe9ef64f93'}},
 'values': {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'),
                         AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'),
                         HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'),
                         AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')],
            'chat': 1},
 'metadata': {'source': 'loop',
              'step': 1,
              'parents': {}},
 'next': ['another_interrupt_node',
          'payment_interrupt_node'],
 'tasks': [{'id': 'fcf8b6bc-0c4a-d439-88f2-f0bf6f160ced',
            'name': 'another_interrupt_node',
            'interrupts': ({'value': 'Send '
                                     'another '
                                     'interrupt(for '
                                     'some '
                                     'reason)',
                            'id': '1635cfd14c3a5b289c981707c2255da7'},),
            'state': None},
           {'id': '34ffbfb5-bd9c-7dae-c41b-6ffc01ac64c6',
            'name': 'payment_interrupt_node',
            'interrupts': (),
            'state': None}]}
[updates] {'payment_interrupt_node': {'interrupt': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), {'role': 'ai', 'content': '30$'}]}}
[updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1, '__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)}
[values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), AIMessage(content='30$', additional_kwargs={}, response_metadata={}, id='83414148-d903-41f9-a726-9853cd82ff3e')], 'interrupt': 1, 'chat': 1}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
state:  StateSnapshot(values={'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1}, next=('another_interrupt_node',), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d17d6-c2fc-6f1c-8001-ed3f54d18cdc'}}, metadata={'source': 'loop', 'step': 1, 'parents': {}}, created_at='2025-12-05T01:55:06.467500+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d17d6-c2f4-6146-8000-26fe9ef64f93'}}, tasks=(PregelTask(id='fcf8b6bc-0c4a-d439-88f2-f0bf6f160ced', name='another_interrupt_node', path=('__pregel_pull', 'another_interrupt_node'), error=None, interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),), state=None, result=None),), interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),))

Description

Scenario

I've implemented a payment-scenario Agent that helps users place an order, then provides a payment link and delivers the product upon successful payment. Users can also choose not to pay and reorder, or simply continue chatting normally.

Issue

After providing the payment link, the agent triggers an Interrupt and waits for the payment result via a callback (which may take 1–2 minutes). To avoid keeping the user idle or bored during this wait, the user is allowed to continue chatting. Once the callback arrives, the system attempts to resume execution using:

Command(
    goto="payment_interrupt_node",
    resume={"data": "30$"}
)

This command jumps to the node responsible for handling the payment result.

However, if there's already an active Interrupt in the graph, the above Command(goto="payment_interrupt_node", ...) fails(don't goto the delivery node).

The key issue lies in the final part—here, two distinct cases can occur:

Command(
    goto="payment_interrupt_node",
    resume={"data": "30$"}
)

CASE_1: another_interrupt_node

Here, another_interrupt_node consumes the resumed data {"data": "30$"}:

[updates] {'another_interrupt_node': {'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}}

However, the corresponding Interrupt does not appear in the StateSnapshot:

[updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)}

CASE_2: payment_interrupt_node

Here, payment_interrupt_node correctly consumes the resumed data {"data": "30$"}:

[updates] {'payment_interrupt_node': {'interrupt': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), {'role': 'ai', 'content': '30$'}]}}

But afterwards, the graph should proceed to the delivery node. Instead, another interrupt is triggered:

[updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)}

Note: the 'interrupt': 1 field does not exist in the StateSnapshot either.

I've implemented handling logic for three cases:

  1. Normal (immediate) payment
  2. Delayed payment with no existing Interrupt
  3. Delayed callback arriving while another Interrupt is already active

Additional Note

This issue might be related to #6533.

System Info

System Information

OS: Darwin
OS Version: Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:40 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8132
Python Version: 3.13.3 (main, Apr 8 2025, 13:54:08) [Clang 17.0.0 (clang-1700.0.13.3)]

Package Information

langchain_core: 1.1.0
langchain: 1.1.0
langsmith: 0.4.49
langgraph_sdk: 0.2.10

Optional packages not installed

langserve

Other Dependencies

httpx: 0.28.1
jsonpatch: 1.33
langgraph: 1.0.4
orjson: 3.11.4
packaging: 25.0
pydantic: 2.12.5
pyyaml: 6.0.3
requests: 2.32.5
requests-toolbelt: 1.0.0
tenacity: 9.1.2
typing-extensions: 4.15.0
zstandard: 0.25.0

Originally created by @li-qingchen on GitHub (Dec 4, 2025). ### Checked other resources - [x] This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/). - [x] I added a clear and detailed title that summarizes the issue. - [x] I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example). - [x] I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue. ### Example Code ```python from pprint import pprint from langchain_core.language_models import FakeListChatModel from langgraph.checkpoint.memory import InMemorySaver from langgraph.graph import StateGraph, MessagesState, START, END from langgraph.types import interrupt, Command class State(MessagesState): interrupt: int chat: int def payment_interrupt_node(state: State): message_list = [] fake_message = FakeListChatModel(responses=["Order creation successful!"]).invoke("") message_list.append(fake_message) payload = interrupt("Payment Link...") data = payload.get("data") # payment data message = payload.get("message") # human message if data: message_list.append({"role": "ai", "content": data}) return Command( goto="delivery", update={ "interrupt": state.get("interrupt", 0) + 1, "messages": message_list } ) if message: message_list.append({"role": "human", "content": message}) if message == "normal conversation": message_list.append({"role": "ai", "content": "relpy message"}) return { "chat": state.get("chat", 0) + 1, "messages": message_list } message_list.append({"role": "ai", "content": "some interrupt"}) return Command( goto="another_interrupt_node", update={ "chat": state.get("chat", 0) + 1, "messages": message_list } ) # Error message_list.append({"role": "ai", "content": "Error!!!"}) return {"messages": message_list} def delivery(state: State): return {"messages": [{"role": "ai", "content": "Delivery message."}]} def another_interrupt_node(state: State): # ... payload = interrupt("Send another interrupt(for some reason)") return {"messages": [ {"role": "human", "content": str(payload)}, {"role": "ai", "content": "never mind"}, ]} # build graph graph = StateGraph(State) graph.add_node(payment_interrupt_node) graph.add_node(delivery) graph.add_node(another_interrupt_node) graph.add_edge(START, "payment_interrupt_node") graph.add_edge("another_interrupt_node", END) graph.add_edge("delivery", END) checkpointer = InMemorySaver() graph = graph.compile(checkpointer=checkpointer) config = {"configurable": {"thread_id": "1"}} # create order and need payment for model, value in graph.stream( {"messages": [{"role": "user", "content": "buy something"}]}, stream_mode=["messages", "updates", "checkpoints"], config=config, debug=True, ): pass # print("model: ", model) # print("value: ") # pprint(value, sort_dicts=False, width=40) print("+" * 100) ################################ Case: Pay Now ########################################## # # # # There is no problem with this case, so let's ignore it # for model, value in graph.stream( # Command(resume={"data": "pay success"}), # stream_mode=["messages", "updates", "checkpoints"], # config=config, # debug=True, # ): # pass # # print("model: ", model) # # print("value: ") # # pprint(value, sort_dicts=False, width=40) ################################ Case: Pay Later (without interrupt) ########################################## # for model, value in graph.stream( # Command(resume={"message": "normal conversation"}), # stream_mode=["messages", "updates", "checkpoints"], # config=config, # debug=True, # ): # pass # # print("model: ", model) # # print("value: ") # # pprint(value, sort_dicts=False, width=40) # # print("+" * 100) # # # then the user paid for the order # for model, value in graph.stream( # Command( # goto="payment_interrupt_node", # resume={"data": "30$"} # ), # stream_mode=["messages", "updates", "checkpoints"], # config=config, # debug=True, # ): # pass # # print("model: ", model) # # print("value: ") # # pprint(value, sort_dicts=False, width=40) ################################ Case: Pay Later (with interrupt) ########################################## for model, value in graph.stream( Command(resume={"message": "ask some information"}), stream_mode=["messages", "updates", "checkpoints"], config=config, debug=True, ): pass # print("model: ", model) # print("value: ") # pprint(value, sort_dicts=False, width=40) print("+" * 100) # there have an interrupt # at same time # then the user paid for the order for model, value in graph.stream( Command( goto="payment_interrupt_node", resume={"data": "30$"} ), stream_mode=["checkpoints"], config=config, debug=True, ): # pass print("model: ", model) print("value: ") pprint(value, sort_dicts=False, width=40) print("+" * 100) # here not go to the delivery node, i don't know why state = graph.get_state(config=config) print("state: ", state) ``` ### Error Message and Stack Trace (if applicable) ```shell [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')]} [updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='c0fb60800beeed446c93ad2b8bf6664a'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')], '__interrupt__': (Interrupt(value='Payment Link...', id='c0fb60800beeed446c93ad2b8bf6664a'),)} ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f')]} [updates] {'payment_interrupt_node': {'chat': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), {'role': 'human', 'content': 'ask some information'}, {'role': 'ai', 'content': 'some interrupt'}]}} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1} [updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1, '__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),)} # CASE_1: another_interrupt_node ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1} model: checkpoints value: {'config': {'configurable': {'checkpoint_ns': '', 'thread_id': '1', 'checkpoint_id': '1f0d0de5-3edf-6edc-8001-cfb96672d6aa'}}, 'parent_config': {'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d0de5-3ed1-6760-8000-d80192f02970'}}, 'values': {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1}, 'metadata': {'source': 'loop', 'step': 1, 'parents': {}}, 'next': ['another_interrupt_node', 'payment_interrupt_node'], 'tasks': [{'id': '082e1f9e-955b-fd99-852f-f6bb62d3c174', 'name': 'another_interrupt_node', 'interrupts': ({'value': 'Send ' 'another ' 'interrupt(for ' 'some ' 'reason)', 'id': 'b51ab1eac2e8c57092a14fc1bce1e4b5'},), 'state': None}, {'id': '36f1a7d2-f471-a97b-536c-a54d7e2862b2', 'name': 'payment_interrupt_node', 'interrupts': (), 'state': None}]} [updates] {'another_interrupt_node': {'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}} [updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b')], 'chat': 1, '__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b'), HumanMessage(content="{'data': '30$'}", additional_kwargs={}, response_metadata={}, id='1a5a6f70-e3f0-4145-a3ac-5627616ecaa4'), AIMessage(content='never mind', additional_kwargs={}, response_metadata={}, id='2605030a-4040-4fbf-aa06-6497ef5123ae')], 'chat': 1} ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ state: StateSnapshot(values={'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='098cc5e6-70d0-49ee-be9d-81e56bda1b9f'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--4167de44-b228-47b7-9b46-264abd1417a4'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='cf6ed29b-0595-4de6-ba9a-10bb537d7584'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d79434ae-2225-49d8-b371-598c7869f92b'), HumanMessage(content="{'data': '30$'}", additional_kwargs={}, response_metadata={}, id='180dc6ad-0733-4c92-92a2-cec63db41c42'), AIMessage(content='never mind', additional_kwargs={}, response_metadata={}, id='11da48f9-fe67-4b0f-ae4c-7a5db0bf4263')], 'chat': 1}, next=(), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d0de5-3edf-6edc-8001-cfb96672d6aa'}}, metadata={'source': 'loop', 'step': 1, 'parents': {}}, created_at='2025-12-04T06:56:15.790857+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d0de5-3ed1-6760-8000-d80192f02970'}}, tasks=(PregelTask(id='082e1f9e-955b-fd99-852f-f6bb62d3c174', name='another_interrupt_node', path=('__pregel_pull', 'another_interrupt_node'), error=None, interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),), state=None, result={'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}),), interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='b51ab1eac2e8c57092a14fc1bce1e4b5'),)) # CASE_2: payment_interrupt_node ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1} model: checkpoints value: {'config': {'configurable': {'checkpoint_ns': '', 'thread_id': '1', 'checkpoint_id': '1f0d17d6-c2fc-6f1c-8001-ed3f54d18cdc'}}, 'parent_config': {'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d17d6-c2f4-6146-8000-26fe9ef64f93'}}, 'values': {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1}, 'metadata': {'source': 'loop', 'step': 1, 'parents': {}}, 'next': ['another_interrupt_node', 'payment_interrupt_node'], 'tasks': [{'id': 'fcf8b6bc-0c4a-d439-88f2-f0bf6f160ced', 'name': 'another_interrupt_node', 'interrupts': ({'value': 'Send ' 'another ' 'interrupt(for ' 'some ' 'reason)', 'id': '1635cfd14c3a5b289c981707c2255da7'},), 'state': None}, {'id': '34ffbfb5-bd9c-7dae-c41b-6ffc01ac64c6', 'name': 'payment_interrupt_node', 'interrupts': (), 'state': None}]} [updates] {'payment_interrupt_node': {'interrupt': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), {'role': 'ai', 'content': '30$'}]}} [updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1, '__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)} [values] {'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), AIMessage(content='30$', additional_kwargs={}, response_metadata={}, id='83414148-d903-41f9-a726-9853cd82ff3e')], 'interrupt': 1, 'chat': 1} ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ state: StateSnapshot(values={'messages': [HumanMessage(content='buy something', additional_kwargs={}, response_metadata={}, id='a50e744d-b5e8-4d95-9388-4e0598481a10'), AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--24a43d8e-20ea-4b1c-b6c4-0ef060565f53'), HumanMessage(content='ask some information', additional_kwargs={}, response_metadata={}, id='506df1b9-42c4-4265-ac56-0b68979f3b41'), AIMessage(content='some interrupt', additional_kwargs={}, response_metadata={}, id='d8ff3231-dfb1-44af-b433-1ca237e4e7d7')], 'chat': 1}, next=('another_interrupt_node',), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d17d6-c2fc-6f1c-8001-ed3f54d18cdc'}}, metadata={'source': 'loop', 'step': 1, 'parents': {}}, created_at='2025-12-05T01:55:06.467500+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f0d17d6-c2f4-6146-8000-26fe9ef64f93'}}, tasks=(PregelTask(id='fcf8b6bc-0c4a-d439-88f2-f0bf6f160ced', name='another_interrupt_node', path=('__pregel_pull', 'another_interrupt_node'), error=None, interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),), state=None, result=None),), interrupts=(Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)) ``` ### Description ## Scenario I've implemented a payment-scenario Agent that helps users place an order, then provides a payment link and delivers the product upon successful payment. Users can also choose not to pay and reorder, or simply continue chatting normally. ## Issue After providing the payment link, the agent triggers an `Interrupt` and waits for the payment result via a callback (which may take 1–2 minutes). To avoid keeping the user idle or bored during this wait, the user is allowed to continue chatting. Once the callback arrives, the system attempts to resume execution using: ```python Command( goto="payment_interrupt_node", resume={"data": "30$"} ) ``` This command jumps to the node responsible for handling the payment result. However, if there's already an active `Interrupt` in the graph, the above `Command(goto="payment_interrupt_node", ...)` fails(don't goto the delivery node). ### The key issue lies in the final part—here, two distinct cases can occur: ```python Command( goto="payment_interrupt_node", resume={"data": "30$"} ) ``` **CASE_1: `another_interrupt_node`** Here, `another_interrupt_node` consumes the resumed data `{"data": "30$"}`: ``` [updates] {'another_interrupt_node': {'messages': [{'role': 'human', 'content': "{'data': '30$'}"}, {'role': 'ai', 'content': 'never mind'}]}} ``` However, the corresponding `Interrupt` does **not** appear in the `StateSnapshot`: ``` [updates] {'__interrupt__': (Interrupt(value='Payment Link...', id='bc79a0ab272d5ba9d239043028d345cd'),)} ``` **CASE_2: `payment_interrupt_node`** Here, `payment_interrupt_node` correctly consumes the resumed data `{"data": "30$"}`: ``` [updates] {'payment_interrupt_node': {'interrupt': 1, 'messages': [AIMessage(content='Order creation successful!', additional_kwargs={}, response_metadata={}, id='lc_run--10a67ac2-ce12-447d-89c6-f04222b74c6d-0'), {'role': 'ai', 'content': '30$'}]}} ``` But afterwards, the graph should proceed to the `delivery` node. Instead, another interrupt is triggered: ``` [updates] {'__interrupt__': (Interrupt(value='Send another interrupt(for some reason)', id='1635cfd14c3a5b289c981707c2255da7'),)} ``` Note: the `'interrupt': 1` field **does not exist** in the `StateSnapshot` either. I've implemented handling logic for three cases: 1. Normal (immediate) payment 2. Delayed payment with no existing `Interrupt` 3. Delayed callback arriving while another `Interrupt` is already active ## Additional Note This issue might be related to #6533. ### System Info System Information ------------------ > OS: Darwin > OS Version: Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:40 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8132 > Python Version: 3.13.3 (main, Apr 8 2025, 13:54:08) [Clang 17.0.0 (clang-1700.0.13.3)] Package Information ------------------- > langchain_core: 1.1.0 > langchain: 1.1.0 > langsmith: 0.4.49 > langgraph_sdk: 0.2.10 Optional packages not installed ------------------------------- > langserve Other Dependencies ------------------ > httpx: 0.28.1 > jsonpatch: 1.33 > langgraph: 1.0.4 > orjson: 3.11.4 > packaging: 25.0 > pydantic: 2.12.5 > pyyaml: 6.0.3 > requests: 2.32.5 > requests-toolbelt: 1.0.0 > tenacity: 9.1.2 > typing-extensions: 4.15.0 > zstandard: 0.25.0
yindo added the bugpending labels 2026-02-20 17:43:00 -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#1081