fix(prebuilt): handle asyncio.CancelledError in ToolNode #6737
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Pull Request: fix(prebuilt): handle asyncio.CancelledError in ToolNode
Summary
This PR fixes issue #6726 where
asyncio.CancelledErroris not caught by theToolNodeerror handling mechanism, even whenhandle_tool_errors=Trueis set.Problem
When a tool execution is cancelled via
asyncio.CancelledError, theToolNodedoes not create an errorToolMessage. This leaves the message history in an invalid state where anAIMessagehastool_callswithout correspondingToolMessages, causingINVALID_CHAT_HISTORYerrors on subsequent LLM calls.Root Cause
asyncio.CancelledErrorinherits fromBaseException, notException. The existing error handling inToolNode._execute_tool_async()and_arun_one()usesexcept Exception as e:, which doesn't catchCancelledError.Solution
except asyncio.CancelledError:handlers before theexcept Exception:blockshandle_tool_errors=True, aToolMessagewithstatus="error"is returnedhandle_tool_errors=False, the exception is re-raised as expectedTOOL_CANCELLED_ERROR_TEMPLATEfor consistent error messagesChanges
libs/prebuilt/langgraph/prebuilt/tool_node.pyAdded constant (line 118):
Modified
_execute_tool_async- Added CancelledError handler before GraphBubbleUp:Modified
_arun_one- Added CancelledError handler for wrapper cancellation:libs/prebuilt/tests/test_tool_node.pyAdded three test cases:
test_tool_node_cancelled_error_handled- Verifies that a ToolMessage with error status is returned whenhandle_tool_errors=Trueand a tool is cancelledtest_tool_node_cancelled_error_not_handled- Verifies that CancelledError is raised whenhandle_tool_errors=Falsetest_tool_node_cancelled_error_in_wrapper- Verifies that CancelledError raised inawrap_tool_callis handled properlyTest Plan
pytest libs/prebuilt/tests/test_tool_node.py -vpytest libs/prebuilt/tests/test_tool_node.py -v -k cancelledReproduction Script (from issue)
Before/After Comparison
handle_tool_errors=True, tool cancelledCancelledErrorraised, no ToolMessagestatus="error"returnedhandle_tool_errors=False, tool cancelledCancelledErrorraisedCancelledErrorraised (unchanged)Related Issues
Checklist