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

ChatDeepSeek Bind_tools(Tool_choice='Any') Produces Invalid Request With Default Thinking Mode

When using ChatDeepSeek with default thinking mode enabled, bind_tools(tool_choice='any') (or True) gets normalized to tool_choice='required', which DeepSeek API rejects with HTTP 400. This is due to lack of validation in ChatDeepSeek for thinking mode constraints.

highConfidence 95%Langchain-DeepseekAffected V1.1.0

Origin Analysis

ChatDeepSeek inherits bind_tools from BaseChatOpenAI, which converts the LangChain 'any' shorthand (and True) to 'required'. DeepSeek's Chat Completions API rejects forced tool_choice (required or named) when thinking mode is enabled. Since thinking mode is enabled by default and ChatDeepSeek does not validate the combination, a deterministic invalid request is produced.
Set DEEPSEEK_API_KEY, then run the provided Python code: instantiate ChatDeepSeek(model='deepseek-flash', max_tokens=256, max_retries=0), bind_tools([TOOL], tool_choice='any') and invoke with a prompt requiring tool call. The API returns 400 error: 'Thinking mode does not support this tool_choice'. The captured request shows tool_choice='required'.

Fixing Code Block

Edge Case Audit

This patch introduces a breaking change for users who relied on bind_tools(tool_choice='any') with default thinking mode; they will now receive a ValueError. Rollback is possible by removing the override. Additionally, the check relies on extra_body merging and may miss cases where thinking mode is set via a different mechanism (e.g., future parameter). The merge assumes extra_body is a dict; if it's None or non-dict, the check may fail. Concurrency is not affected as this is a stateless method on the model instance.

Ecosystem Topology