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

Langchain-Openai: Named Tool_choice Rejected By Qwen Thinking Mode (DashScope)

ChatOpenAI with extra_body={"enable_thinking": true} and bind_tools(..., tool_choice="get_weather") sends a named tool-choice object to Alibaba DashScope, which rejects it with InternalError.Algo.InvalidParameter. LangChain should validate this incompatible combination before sending the request.

mediumConfidence 75%LangChainAffected V1.6.6

Origin Analysis

langchain-openai forwards the forced tool_choice object unchanged when enable_thinking is turned on. DashScope's OpenAI-compatible API does not support object/required tool_choice in thinking mode, and LangChain lacks a pre-flight validation layer, so the raw client error reaches the end user instead of a clear local exception.
Set DASHSCOPE_API_KEY. Create ChatOpenAI with base_url=https://dashscope.aliyuncs.com/compatible-mode/v1, model='qwen3.8-max', extra_body={'enable_thinking': True}. Call bind_tools([tool], tool_choice='get_weather') and invoke. The server returns 400 InternalError.Algo.InvalidParameter: tool_choice parameter does not support being set to required or object in thinking mode.

Fixing Code Block

def _get_request_payload(self, input_, *, stop=None, **kwargs): payload = super()._get_request_payload(input_, stop=stop, **kwargs) if (self.extra_body or {}).get("enable_thinking"): tool_choice = payload.get("tool_choice") if tool_choice not in (None, "none", "auto"): raise ValueError( "enable_thinking=True is incompatible with forced tool choice; " f"got {tool_choice!r}. Use tool_choice='auto' or disable thinking." ) return payload
The patch overrides ChatOpenAI._get_request_payload to add a request-time guard. After the normal payload is built, it checks whether the instance has enable_thinking set in extra_body. If so, and the resolved tool_choice is anything other than None, 'none', or 'auto', it raises a ValueError with a clear message. This avoids silently changing either the tool choice or thinking mode, and returns the error before any HTTP request is made.

Edge Case Audit

This client-side guard is provider-agnostic and may block forced tool_choice+thinking combinations on other OpenAI-compatible providers that actually support them. The check only looks at enable_thinking and ignores the base_url/model, so if DashScope later adds support or if users rely on this combination elsewhere, the exception would be false-positive. If extra_body is mutated after model binding, use the bound instance's copy rather than shared state. Rollback: remove this override or set enable_thinking=False to restore the previous behavior.

Ecosystem Topology