AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

ChatOpenAI.Stream() Crashes On A Mocked Tool-Call Delta With Null Function

The public ChatOpenAI.stream() API raises AttributeError when an OpenAI streaming chunk contains a tool-call delta whose `function` field is null. The parser assumes `rtc["function"]` is a dict and calls `.get` on None, causing a crash. Even though the repro uses a mocked response, the public API should handle malformed or unexpected provider payloads gracefully.

mediumConfidence 85%LangChainAffected V1.6.6

Origin Analysis

In `langchain_openai/chat_models/base.py`, `_convert_delta_to_message_chunk` constructs `ToolCallChunk` objects by directly calling `rtc["function"].get("name")` and `.get("arguments", "")` without checking if `rtc["function"]` is `None`. When the provider sends `"function": null`, the `.get` call on `None` raises `AttributeError`.
Install langchain-openai==1.6.6 and httpx==0.28.1. Run the provided script that uses httpx.MockTransport to return a chat completion chunk with `"function": None` inside a tool_call delta. Observe that `list(llm.stream("Call the tool"))` raises `AttributeError: 'NoneType' object has no attribute 'get'`.

Fixing Code Block

tool_call_chunks = [ ToolCallChunk( name=(rtc.get("function") or {}).get("name"), args=(rtc.get("function") or {}).get("arguments", ""), id=rtc.get("id"), index=rtc["index"], type=rtc.get("type"), ) for rtc in raw_tool_calls ]
Replace the direct `rtc["function"].get(...)` calls with `(rtc.get("function") or {}).get(...)`. This tolerates a missing or null `function` field by treating it as an empty dict, producing a `ToolCallChunk` with `name=None` and `args=""` instead of crashing. The chunk is still emitted, allowing downstream merging to combine later chunks that contain actual function details.

Edge Case Audit

This fix treats a null function as an empty dict, resulting in `args=""` rather than `None`. In LangChain's tool call merging, an empty string may be concatenated with subsequent argument chunks; if the provider relies on `None` to signal 'no update', this could change final tool call arguments. Test with real partial tool-call sequences before deploying. If unexpected tool call merging issues appear, rollback to the original code and instead filter out tool calls with null function or raise a clearer error. The fix only addresses the null `function` field; other malformed fields may still cause crashes.

Ecosystem Topology