langchain · difficulty ◆◆◆
ChatOpenAI Tool-Call Filtering via _convert_responses_to_tool_calls
Drop the malformed tool calls before they crash your agent loop.
Models rarely emit a malformed tool call - but when they do, your entire agent loop can die on it.
$ pip install -U langchain-openai==1.4.3What it does
langchain-openai==1.4.3 ships a bug fix that filters invalid tool calls from model content (#39366). With ChatOpenAI\u2019s Responses API and bind_tools, the model can occasionally emit a malformed tool call - one whose id is missing, whose arguments fail to parse as JSON, or that references a tool name not in your bound schema. Previously these passed straight through to your loop, raising confusing KeyError/JSONDecodeError exceptions deep in your agent code. Now LangChain detects and drops them, so your tool_calls list only ever contains well-formed entries.
Why it matters
Tool calling is the backbone of every agentic app - a ReAct loop, a function-calling router, a multi-step research agent all depend on trustworthy tool calls. A single malformed call can crash an entire agent run in production, and because models rarely emit bad calls, it is intermittent and brutal to reproduce. This fix hardens your loop for free: you no longer need defensive try/except wrappers around every tool dispatch to guard against garbage from the model.
Example
$ Inject one valid and one malformed tool call, see only the valid surviveValid tool calls after filtering:
- get_weather({'city': 'Vienna'}) [id=call_1]The malformed second call (missing id, non-JSON args) is dropped before reaching your handler.
$ The malformed call that used to crash loops in 1.4.2malformed.tool_calls = [
{"name": "get_weather", "args": {"city": "Vienna"}, "id": "call_1"},
{"name": "get_weather", "args": "not-json", "id": None}, # dropped in 1.4.3
]Common flags
- #39366
- fix: filter invalid tool calls from model content.
- bind_tools
- Attaches a tool schema so the model can emit tool calls.
- ToolNode
- Executes tool calls in an agent graph, consuming the filtered list.
History
Trust but verify
LLMs are probabilistic, so their tool calls occasionally deviate from the schema - a dropped id, a non-JSON argument blob. LangChain initially forwarded these verbatim, treating the model as always-correct. The 1.4.3 fix adds a verification pass in the Responses-API converter, adopting the \u201ctrust but verify\u201d posture that production agents need.
Fun facts
Pros & cons
pros
- + No more crash-on-garbage
- + Cleaner agent loops
- + Intermittent bugs removed for free
cons
- − Dropped calls are not retried automatically
- − You still validate at the boundary you trust
Takeaways
- 1Upgrade to langchain-openai>=1.4.3.
- 2Trust the filtered tool_calls but keep a boundary backstop.
- 3Log dropped calls if you want visibility into model drift.