Checked other resources
Example Code
from langchain_core.messages.tool import default_tool_parser, default_tool_chunk_parser
# Case 1: function value is None
raw = [{"function": None, "id": "call_1"}]
default_tool_parser(raw) # TypeError
# Case 2: function dict missing keys
raw = [{"function": {}, "id": "call_1"}]
default_tool_parser(raw) # KeyError: name
# Case 3: One malformed call drops ALL valid calls
raw = [
{"function": None, "id": "bad"},
{"function": {"name": "good_tool", "arguments": "{\"a\": 1}"}, "id": "good"},
]
default_tool_parser(raw) # Crashes on first item, good call never parsed
Error Message and Stack Trace
TypeError: NoneType object is not subscriptable
KeyError: name
Description
default_tool_parser and default_tool_chunk_parser in langchain_core/messages/tool.py crash with unhandled KeyError/TypeError when a raw tool call has a malformed function field.
Root cause: Both functions check if "function" not in raw_tool_call but do not validate that the value is actually a dict with the expected keys. They use direct indexing (raw_tool_call["function"]["name"]) instead of .get().
Impact: When ANY single tool call in a list is malformed, the exception kills the entire parsing loop. The caller in ai.py catches Exception broadly, so ALL tool calls (including valid ones) are silently dropped. This is problematic because:
- The function is documented as Best-effort parsing but is actually all-or-nothing
default_tool_parser already has an invalid_tool_calls return list for exactly this purpose, but malformed function dicts never reach it
Affected functions:
default_tool_parser (line 361): function_name = raw_tool_call["function"]["name"]
default_tool_chunk_parser (lines 405-406): tool_call["function"]["arguments"] and tool_call["function"]["name"]
System Info
langchain-core latest (main branch as of 2025-07-12)
Checked other resources
Example Code
Error Message and Stack Trace
Description
default_tool_parseranddefault_tool_chunk_parserinlangchain_core/messages/tool.pycrash with unhandledKeyError/TypeErrorwhen a raw tool call has a malformedfunctionfield.Root cause: Both functions check
if "function" not in raw_tool_callbut do not validate that the value is actually a dict with the expected keys. They use direct indexing (raw_tool_call["function"]["name"]) instead of.get().Impact: When ANY single tool call in a list is malformed, the exception kills the entire parsing loop. The caller in
ai.pycatchesExceptionbroadly, so ALL tool calls (including valid ones) are silently dropped. This is problematic because:default_tool_parseralready has aninvalid_tool_callsreturn list for exactly this purpose, but malformed function dicts never reach itAffected functions:
default_tool_parser(line 361):function_name = raw_tool_call["function"]["name"]default_tool_chunk_parser(lines 405-406):tool_call["function"]["arguments"]andtool_call["function"]["name"]System Info
langchain-core latest (main branch as of 2025-07-12)