Symptom
A tool that calls interrupt() emits a tools stream event {'event': 'tool-error', 'tool_call_id': 'tc1', 'message': "(Interrupt(value='ok?', id='...'),)"} instead of pausing only on __interrupt__. The structured Interrupt id and value are flattened to str(error).
Evidence what you'll see
- The report's print for
stream_mode=["tools"]is{'event': 'tool-started', ...}then thattool-errorpayload. The expected tools stream is onlytool-started. - The handler is
StreamToolCallHandler._errorinlibs/langgraph/langgraph/pregel/_tools.py, which sends"event": "tool-error"and"message": str(error)for every exception. - Reproduced on
mainand on langgraph 1.2.6, Python 3.12.
Why it happens
GraphInterrupt is a GraphBubbleUp control-flow pause, not a tool failure. _runner, _executor, and _retry already skip GraphBubbleUp. The tools stream handler does not, so a pause is labeled tool-error and the Interrupt objects are lost.
Affected versions
langgraph 1.2.6 and main, Python 3.12. The linked issue does not name an operating system.
Fix steps
0 of 2 done
Your check marks stay in this browser only.
How to check it worked
- A tool that
return interrupt(question)emitstool-startedon the tools stream and notool-error, andgraph.get_state(config).interruptsstill has the Interrupt id and value.
If it still fails
- Pull requests 8219 and 8282 skip
tool-errorwhenisinstance(error, GraphBubbleUp)and were closed without merge. - The linked issue does not name a release that keeps the Interrupt payload on the tools stream.
Sources and credit
Summarized in our own words from these public reports. Credit goes to their authors.
Provided as is, without warranty. Try changes in a non-production environment and back up first. Security-related steps: verify against the official docs. Terms · Request removal or attribution change
Hit an error we don't cover? Submit it