Skip to content

fix(python): retry with auto tool choice when a model rejects forced tool choice - #5172

Draft
mehtarac wants to merge 1 commit into
strands-agents:mainfrom
mehtarac:fix_forced_tool_issue
Draft

mehtarac wants to merge 1 commit into
strands-agents:mainfrom
mehtarac:fix_forced_tool_issue

Conversation

@mehtarac

Copy link
Copy Markdown
Member

Human Overview

Description

Claude Opus 5.5 and Sonnet 5.5 reject forced tool choice (tool_choice any/tool), so when one of them answers in prose instead of calling the structured output tool, the forced retry fails with a raw ValidationException rather than producing structured output or StructuredOutputException. The deprecated agent.structured_output() path fails the same way.

BedrockModel and AnthropicModel now recognize that specific rejection, resend the request once with auto inside the same model call, and remember the model for the process so later requests send auto up front. Capability is learned from the provider's error rather than a model list, following the existing CountTokens cache. Models that accept forced tool choice are unaffected, and if the model still skips the tool, the existing check raises StructuredOutputException.

This is an interim fix: auto makes the tool call likely, not guaranteed. A follow-up uses native structured output on these models to restore the guarantee.

Related Issues

Fixes #5156

Documentation PR

No docs change needed for this behavior fix.

Type of Change

Bug fix

Testing

Ran the models, event loop, structured output and agent unit suites. Live on Bedrock: Opus 5.5, Sonnet 5.5 and Haiku 5.5 through both BedrockModel and AnthropicModel (via AsyncAnthropicBedrock), with an extra tool in the agent; all produced structured output, and debug logs confirmed the fallback ran only on the 5.5 models and only on the first call. The deprecated path succeeded on all three, and a prompt telling the model never to call tools ended in StructuredOutputException. Not verified: Fable 5.1 and a direct Anthropic API key.

  • I ran hatch run prepare

Additional Details

Extended context (optional)

Raw Converse probe of tool_choice per model:

Model auto any / tool
Opus 5.5, Sonnet 5.5 OK 400: tool_choice: type "tool" and "any" are not supported for this model.
Haiku 5.5, Opus 5, Sonnet 4.5 OK OK

The rejected request fails in validation (~250 ms, no token usage), so the fallback costs one fast request per model per process.

Checklist

  • I have read the CONTRIBUTING document
  • I have reviewed and understand every line of code in this PR, including any generated by AI tools, and I can explain why it works
  • My change is focused and reasonably small; I have split unrelated work into separate PRs
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

🤖 Generated with Claude Code

…tool choice

Claude Opus 5.5 and Sonnet 5.5 reject tool_choice any/tool, so the forced
structured output retry failed with a raw ValidationException. BedrockModel
and AnthropicModel now detect that rejection, resend the request once with
auto tool choice, and remember the model so later requests send auto up
front. If the model still skips the tool, the existing check raises
StructuredOutputException.

Fixes strands-agents#5156

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added python Pull requests that update python code area-model Related to models or model providers area-structured-output Related to the structured output api bug Something isn't working complexity/high A touched function exceeds cognitive complexity 25; may be worth splitting size/m labels Oct 15, 2026
@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-model Related to models or model providers area-structured-output Related to the structured output api bug Something isn't working complexity/high A touched function exceeds cognitive complexity 25; may be worth splitting python Pull requests that update python code size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Structured output fails with a 400 on Claude Opus 5.5 / Sonnet 5.5 / Fable 5.1 because the forced tool_choice fallback is rejected

1 participant