Second interrupt() during streaming graph doesn’t emit "__interrupt__" event

I’m building a LangGraph flow that calls interrupt() from inside a ToolNode, resumes the run while streaming (graph.stream(Command(resume=input_value))), then eventually finishes the tool and returns control to the node that originally invoked it which call a tool again (without finishing the thread) with interrupt() in it.

The first interrupt() works perfectly: the graph output stream includes the {"__interrupt__": …} envelope and I can resume as expected.

The second (and any subsequent) interrupt() does stop execution, but I get no "__interrupt__" indication in the streamed output. From the outside it just looks like the graph stalls—no error, no event, nothing to resume.

# simplified setup
def tool_node(state): # first pause
if state.get("stage") == 0:
state["stage"] = 1
interrupt() # <- emits "__interrupt__"
return state
# do some work, then try pausing again

if state.get("stage") == 1:
state["stage"] = 2
interrupt() # <- halts, but emits nothing
return state # finish

graph = Graph()
graph.add_node(tool_node)

# run runner = graph.stream({"stage": 0}) # => first interrupt event arrives; I call `graph.stream((Command(resume="foo"))` # ...second interrupt triggers but no "__interrupt__" appears

This occurs because LangGraph uses internal execution queues and the interrupt stream envelope is only surfaced once per event loop phase unless resumed. On LangGraph Platform, only the first interrupt emits an __interrupt__ event, subsequent interrupts don’t re-surface until you complete a resume cycle.

The resume cycle effect: After calling graph.stream(Command(resume="...")), execution continues and the next interrupt() can emit the event again.

Workaround: add state indicators:

def tool_node(state):
    if state.get("stage") == 1:
        state["interrupted_stage"] = "stage_2"
        interrupt("Paused at stage 2")
        return state

Detection strategies:

  • Monitor stream timing for stalled chunks

  • Check run status via API for interrupted state

  • Use state-based signaling before interrupt()

The graph remains alive awaiting resume, it doesn’t halt permanently. Test multi-interrupt flows on the platform since behavior differs from local execution.

Thanks for the response.

It sounds like this is at least partially our problem, but some issues remains unclear.
how do you define a “completion of a resume cycle”?
This is our flow:
Agent ingest user message, call tool-1 which emits an interrupt, this is caught by our BE which triggers a re invocation with graph.stream(Command(resume="...")). It then returns to tool-1, finish it, returns to the agent which now calls tool-2. tool-2 tries to emit an interrupt, but this is not caught in the graph stream.

We assumed once we call graph.stream(Command(resume="..."))a new cycle begin, therefore enabling the graph to emit the new interrupt.
I don’t think that using the state indicator will work in this case, because tool-2 is being called in that same cycle and must emit an interrupt.

The only time this works for us, is when the stream ends and we start a new stream, enabling us to emit a new interrupt