langchain - ✅(Solved) Fix Problems with thinking/reasoning and structured output for tools using Anthropic [3 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
langchain-ai/langchain#36418Fetched 2026-04-08 02:22:28
View on GitHub
Comments
2
Participants
3
Timeline
14
Reactions
0
Timeline (top)
labeled ×4cross-referenced ×3referenced ×3commented ×2
  • I'm trying to add some thinking to my agents, using structured output for correct parameter provisioning in tools
  • I expect it to show thinking without issues related to tools
  • Instead I get an error due to tool_choice being hardcoded to any, which Anthropic doesn't support when Thinking:

https://github.com/langchain-ai/langchain/blob/f94d4215a41f2444e52315d6903a9c7e0c972b26/libs/langchain_v1/langchain/agents/factory.py#L1251

Reference

In this link Anthropic explains more about it: https://platform.claude.com/docs/en/build-with-claude/extended-thinking#extended-thinking-with-tool-use

Error Message

import asyncio import os

from deepagents import create_deep_agent from langchain.agents import create_agent from langchain_anthropic import ChatAnthropic from pydantic import BaseModel, Field, SecretStr

class AgentSummary(BaseModel): """Final structured response from the agent.""" summary: str = Field(description="Summary of what the agent accomplished.")

model = ChatAnthropic( model_name="claude-sonnet-4-6", api_key=SecretStr(os.environ["ANTHROPIC_API_KEY"]), thinking={"type": "enabled", "budget_tokens": 1024}, timeout=None, stop=None )

def echo(text: str) -> str: """Echo the input text back.""" return text

deep_agent = create_deep_agent( model, tools=[echo], response_format=AgentSummary, )

async def main(): print("Invoking agent …") try: result = await deep_agent.ainvoke({"messages": [{"role": "user", "content": "Echo 'hello world' and summarise."}]}) print("structured_response:", result.get("structured_response")) except Exception as exc: print(f"\n[ERROR] {type(exc).name}: {exc}\n")

if name == "main": asyncio.run(main())

Root Cause

  • I'm trying to add some thinking to my agents, using structured output for correct parameter provisioning in tools
  • I expect it to show thinking without issues related to tools
  • Instead I get an error due to tool_choice being hardcoded to any, which Anthropic doesn't support when Thinking:

https://github.com/langchain-ai/langchain/blob/f94d4215a41f2444e52315d6903a9c7e0c972b26/libs/langchain_v1/langchain/agents/factory.py#L1251

Reference

In this link Anthropic explains more about it: https://platform.claude.com/docs/en/build-with-claude/extended-thinking#extended-thinking-with-tool-use

Fix Action

Fix / Workaround

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Other Dependencies

anthropic: 0.87.0 filetype: 1.2.0 google-genai: 1.57.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.0.9 ollama: 0.6.1 openai: 2.30.0 orjson: 3.11.5 packaging: 25.0 pydantic: 2.12.5 pytest: 9.0.2 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 rich: 13.9.4 tenacity: 9.1.2 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.13.0 zstandard: 0.25.0

PR fix notes

PR #7386: fix(prebuilt): strip extended thinking before with_structured_output to avoid Anthropic tool_choice error

Description (problem / solution / changelog)

Fixes langchain-ai/langchain#36418

When Anthropic extended thinking is enabled on a model (thinking.type == "enabled" or "adaptive"), the Anthropic API rejects tool_choice="any" or tool_choice="tool". with_structured_output uses tool_choice="any" by default for Anthropic models, causing a 400 error:

Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error',
'message': 'Thinking may not be enabled when tool_choice forces tool use.'}}

This surfaces whenever response_format is used together with a thinking-enabled ChatAnthropic model in create_react_agent (and the new create_agent in langchain).

Changes

libs/prebuilt/langgraph/prebuilt/chat_agent_executor.py

  • Added _strip_thinking_if_enabled(model: BaseChatModel) -> BaseChatModel helper.
    It checks for a thinking dict attribute whose type is not None/"disabled", and returns a model_copy(update={"thinking": {"type": "disabled"}}) in that case. Models without thinking are returned unchanged (same object, no copy made).

  • Applied the helper in both generate_structured_response and agenerate_structured_response before calling .with_structured_output(...). The structured-response call is a separate LLM invocation that occurs after the main tool-use loop, so thinking is not needed there and stripping it avoids the API constraint.

libs/prebuilt/tests/test_react_agent.py

  • FakeThinkingModel — test-double that raises the Anthropic error string when with_structured_output is called while thinking is enabled.
  • test_strip_thinking_if_enabled — unit tests for all thinking states (absent, None, "disabled", "enabled", "adaptive").
  • test_react_agent_structured_response_strips_thinking[v1/v2] — end-to-end test verifying the fix.

Verification

# All new tests pass, no regressions in existing structured-output tests
python -m pytest \
  tests/test_react_agent.py::test_strip_thinking_if_enabled \
  "tests/test_react_agent.py::test_react_agent_structured_response_strips_thinking[v1]" \
  "tests/test_react_agent.py::test_react_agent_structured_response_strips_thinking[v2]" \
  tests/test_react_agent.py::test_react_agent_with_structured_response \
  tests/test_react_agent.py::test_get_model \
  tests/test_react_agent.py::test_dynamic_model_with_structured_response \
  tests/test_react_agent.py::test_post_model_hook_with_structured_output
# 9 passed

ruff check and ruff format --check both pass.

Social handles (optional)

Twitter: @ LinkedIn: https://linkedin.com/in/

Changed files

  • libs/prebuilt/langgraph/prebuilt/chat_agent_executor.py (modified, +21/-4)
  • libs/prebuilt/tests/test_react_agent.py (modified, +87/-2)

PR #36476: Fix(agents): Avoid forcing tool_choice='any' when Anthropic thinking, #36418

Description (problem / solution / changelog)

Fixes #36418

Fix

Avoid forcing tool_choice="any" when using Anthropic models with thinking enabled, as this causes API error with structured output.

How did you verify your code works?

Ran relevant unit tests locally to ensure no regressions in agent behavior.


This change preserves existing behavior when thinking is disabled.

Changed files

  • libs/langchain_v1/langchain/agents/factory.py (modified, +9/-1)

PR #36532: Fix/anthropic thinking tool choice

Description (problem / solution / changelog)

Fixes #36418

This PR resolves a 400 Bad Request error by preventing tool_choice="any" from being hardcoded when Anthropic's "Extended Thinking" is enabled alongside structured output tools. It introduces a check in the agent factory to ensure tool_choice defaults to auto when thinking is active, complying with Anthropic's API constraints.

Read the full contributing guidelines: https://docs.langchain.com/oss/python/contributing/overview

All contributions must be in English. See the language policy.

If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!

Thank you for contributing to LangChain! Follow these steps to have your pull request considered as ready for review.

PR title: Should follow the format: TYPE(SCOPE): DESCRIPTION

Examples:

fix(anthropic): resolve flag parsing error

feat(core): add multi-tenant support

test(openai): update API usage tests

Allowed TYPE and SCOPE values: https://github.com/langchain-ai/langchain/blob/master/.github/workflows/pr_lint.yml#L15-L33

PR description:

Write 1-2 sentences summarizing the change.

The Fixes #xx line at the top is required for external contributions — update the issue number and keep the keyword. This links your PR to the approved issue and auto-closes it on merge.

If there are any breaking changes, please clearly describe them.

If this PR depends on another PR being merged first, please include "Depends on #PR_NUMBER" in the description.

Run make format, make lint and make test from the root of the package(s) you've modified.

We will not consider a PR unless these three are passing in CI.

How did you verify your code works?

Added a unit test validating that tool_choice is not forced to "any" when thinking={"type": "enabled"} is present in the model configuration.

Executed the reproduction script provided in Issue #36418 to verify the API no longer returns the 400 error.

Additional guidelines:

All external PRs must link to an issue or discussion where a solution has been approved by a maintainer, and you must be assigned to that issue. PRs without prior approval will be closed.

PRs should not touch more than one package unless absolutely necessary.

Do not update the uv.lock files or add dependencies to pyproject.toml files (even optional ones) unless you have explicit permission to do so by a maintainer.

Social handles (optional)

LinkedIn: https://linkedin.com/in/arbab-riffat-shahnawaz/

Changed files

  • libs/langchain_v1/langchain/agents/factory.py (modified, +17/-8)
  • libs/langchain_v1/langchain/agents/fix #36418.md (added, +43/-0)
  • libs/langchain_v1/langchain/agents/test_anthropic_thinking.py (added, +8/-0)

Code Example

import asyncio
import os

from deepagents import create_deep_agent
from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from pydantic import BaseModel, Field, SecretStr


class AgentSummary(BaseModel):
    """Final structured response from the agent."""
    summary: str = Field(description="Summary of what the agent accomplished.")

model = ChatAnthropic(
    model_name="claude-sonnet-4-6",
    api_key=SecretStr(os.environ["ANTHROPIC_API_KEY"]),
    thinking={"type": "enabled", "budget_tokens": 1024},
    timeout=None,
    stop=None
)

def echo(text: str) -> str:
    """Echo the input text back."""
    return text

deep_agent = create_deep_agent(
    model,
    tools=[echo],
    response_format=AgentSummary,
)

async def main():
    print("Invoking agent …")
    try:
        result = await deep_agent.ainvoke({"messages": [{"role": "user", "content": "Echo 'hello world' and summarise."}]})
        print("structured_response:", result.get("structured_response"))
    except Exception as exc:
        print(f"\n[ERROR] {type(exc).__name__}: {exc}\n")


if __name__ == "__main__":
    asyncio.run(main())

---

Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'Thinking may not be enabled when tool_choice forces tool use.'}, 'request_id': 'req_011CZcQxZPodHji6qwGXL6jd'}
RAW_BUFFERClick to expand / collapse

Checked other resources

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-openrouter
  • langchain-perplexity
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Related Issues / PRs

No response

Reproduction Steps / Example Code (Python)

import asyncio
import os

from deepagents import create_deep_agent
from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from pydantic import BaseModel, Field, SecretStr


class AgentSummary(BaseModel):
    """Final structured response from the agent."""
    summary: str = Field(description="Summary of what the agent accomplished.")

model = ChatAnthropic(
    model_name="claude-sonnet-4-6",
    api_key=SecretStr(os.environ["ANTHROPIC_API_KEY"]),
    thinking={"type": "enabled", "budget_tokens": 1024},
    timeout=None,
    stop=None
)

def echo(text: str) -> str:
    """Echo the input text back."""
    return text

deep_agent = create_deep_agent(
    model,
    tools=[echo],
    response_format=AgentSummary,
)

async def main():
    print("Invoking agent …")
    try:
        result = await deep_agent.ainvoke({"messages": [{"role": "user", "content": "Echo 'hello world' and summarise."}]})
        print("structured_response:", result.get("structured_response"))
    except Exception as exc:
        print(f"\n[ERROR] {type(exc).__name__}: {exc}\n")


if __name__ == "__main__":
    asyncio.run(main())

Error Message and Stack Trace (if applicable)

Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'Thinking may not be enabled when tool_choice forces tool use.'}, 'request_id': 'req_011CZcQxZPodHji6qwGXL6jd'}

Description

  • I'm trying to add some thinking to my agents, using structured output for correct parameter provisioning in tools
  • I expect it to show thinking without issues related to tools
  • Instead I get an error due to tool_choice being hardcoded to any, which Anthropic doesn't support when Thinking:

https://github.com/langchain-ai/langchain/blob/f94d4215a41f2444e52315d6903a9c7e0c972b26/libs/langchain_v1/langchain/agents/factory.py#L1251

Reference

In this link Anthropic explains more about it: https://platform.claude.com/docs/en/build-with-claude/extended-thinking#extended-thinking-with-tool-use

System Info

System Information

OS: Linux OS Version: #20.01.00.10 SMP PREEMPT_DYNAMIC Thu Jun 15 16:17:50 CST 2023 Python Version: 3.13.11 (main, Dec 8 2025, 11:43:54) [GCC 15.2.0]

Package Information

langchain_core: 1.2.13 langchain: 1.2.10 langsmith: 0.6.2 langchain_anthropic: 1.3.3 langchain_google_genai: 4.2.0 langchain_ollama: 1.0.1 langchain_openai: 1.1.9 langgraph_sdk: 0.3.8

Optional packages not installed

langserve

Other Dependencies

anthropic: 0.87.0 filetype: 1.2.0 google-genai: 1.57.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.0.9 ollama: 0.6.1 openai: 2.30.0 orjson: 3.11.5 packaging: 25.0 pydantic: 2.12.5 pytest: 9.0.2 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 rich: 13.9.4 tenacity: 9.1.2 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.13.0 zstandard: 0.25.0

extent analysis

TL;DR

The most likely fix is to disable thinking when using tools with Anthropic by setting tool_choice to a value other than any or by disabling thinking altogether.

Guidance

  • The error occurs because Anthropic does not support thinking when tool_choice is set to any, which is the default value in LangChain.
  • To fix this, you can try setting tool_choice to a specific value, such as latest, or disable thinking by setting thinking to None or an empty dictionary.
  • You can also try updating the langchain package to the latest version, as the issue may have been fixed in a newer release.
  • Additionally, you can check the Anthropic documentation for more information on how to use thinking with tools.

Example

model = ChatAnthropic(
    model_name="claude-sonnet-4-6",
    api_key=SecretStr(os.environ["ANTHROPIC_API_KEY"]),
    thinking=None,  # Disable thinking
    timeout=None,
    stop=None
)

Notes

  • The fix may depend on the specific use case and requirements of your application.
  • Disabling thinking may affect the performance and accuracy of your agent.

Recommendation

Apply workaround: Disable thinking when using tools with Anthropic by setting thinking to None or an empty dictionary. This is a safe and straightforward solution that should resolve the error.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING