Claude Fable 5.1 Won't Force a Tool Call Anymore. It Returns a 400 Instead.
If your agent code sets tool_choice: "any" or names a specific tool by ID, Claude Fable 5.1 will not comply anymore. It returns a 400 error instead, on every account, with no opt-out. This isn't a gradual deprecation with a warning header. It's a hard rejection that shipped with the model, and if you built an agent pipeline against the old forced-tool-call pattern sometime in the last year or two, it is already broken. You just might not have noticed yet, because the failure mode is a stack trace in a retry queue, not a page falling over.
Why Anthropic made this call
Fable 5.1 runs extended thinking on by default, for every request, not as an opt-in flag. Forcing a tool call used to mean the model skipped straight to producing tool arguments, no reasoning step in between. That was fine for older models that didn't have an always-on thinking mode to skip. For 5.1, forcing the call meant the model would shove its reasoning into the tool arguments themselves, since it had nowhere else to put it, which quietly degraded the quality of what actually got passed to your tool. Anthropic's documented answer wasn't "let people force it anyway and eat the quality hit." It was "stop letting people force it at all."
The two settings that still work are tool_choice: "auto" (the default) and tool_choice: "none". Everything in between, "any" or a specific named tool, now 400s.
What still works
The migration guide gives you three real paths, and none of them require restructuring your whole agent loop:
- Keep
tool_choice: "auto", but be explicit in the prompt about when a tool applies. Something as blunt as "use the get_weather tool to answer this" in the user turn or a mid-conversation system message does the job that forced tool_choice used to do. - Pair that with
strict: trueon your tool definitions, so you still get schema-valid arguments even though the model technically chose to call the tool rather than being compelled to. - If what you actually wanted was guaranteed JSON shape rather than a guaranteed tool call, move to structured outputs directly instead of routing through tool-calling as a JSON-enforcement hack, which is what a lot of forced-tool-call code was really doing anyway.
None of this is exotic. It's a config change plus a prompt tweak in most cases. The part that bites people is not knowing you need to make it until a production agent starts throwing 400s at 2am with no changelog alert, because nobody's monitoring dashboard is set up to catch "API contract changed under me," only "API is down."
Where this shows up in practice
I went back through three small agent scripts I run for content research and one for issue triage on a side project, and two of the three had a tool_choice: {"type": "tool", "name": "..."} block sitting in code I hadn't touched since it worked the first time. That's the exact pattern this change kills. Neither one had failed yet when I checked, only because I hadn't pushed a dependency bump that would've pulled in whatever client version enforces the new behavior server-side. That's not a safety margin, it's a countdown.
If you're running any agent framework that abstracts tool_choice for you (LangChain-style wrappers, custom orchestration layers, anything that decided for you at some point that "force the tool" was the reliable way to get structured output), go find where that decision was made and confirm it's not still setting tool_choice: "any" under the hood. A wrapper library update might already have patched around this without telling you, or might not have gotten to it yet.
The honest take
I think Anthropic made the correct call here. A forced tool call that quietly produces worse arguments because the model has nowhere to think is a worse failure mode than an explicit 400 you have to go fix once. Silent quality degradation is the kind of bug that costs you a week of "why does this agent occasionally do something dumb" before anyone traces it back to the tool_choice setting.
Where I'd push back a little: a hard 400 with zero grace period is rough for anyone not actively watching the model's own changelog, which is most solo operators running one or two agent scripts as a side concern rather than a core product. A short deprecation window with a warning response before the hard cutover would have caught more of these before they became production incidents instead of after. If you ship anything that calls Claude models with tool use, the actual to-do item today is: grep your codebase for tool_choice, check what it's set to, and fix it now instead of finding out from an error log later.
Author
Lukas
@lukcombinator