Skip to content

tool_choice: {"type": "any"} on every call: no text answer on Claude Fable 5, hard 400 on Claude Fable 5.1 #5

Description

@atilavahedian

src/core/driver.py (around line 516, at b0e3435) sends tool_choice={"type": "any"} on
every messages.create call, including the follow-up calls inside the tool loop. Two
consequences, one old and one new:

1. On current Claude models the driver can never return a text answer. With
{"type":"any"}, every response is forced to contain a tool_use block, so the loop at
driver.py:~250-283 runs until max_iterations, and the text extraction after it finds no
text blocks — the user gets the "unable to generate a proper response" fallback. Observed
against claude-fable-5, 5 runs each of two README questions ("What companies are in the
technology sector?" and a Q1-2025 revenue question): 0/5 and 0/5 produced any text; each
run made six forced SQL_QueryReadonly calls (SELECT * FROM companies WHERE sector = 'Technology', then narrower variants) before hitting the cap. Input tokens per call grew
from 1,123 to 3,301 across the forced turns.

2. On Claude Fable 5.1 (released 2026-09-01) the same request is rejected outright:

tool_choice: type "tool" and "any" are not supported for this model.

HTTP 400, invalid_request_error, quoted verbatim from a recorded response; 10/10 runs.
Anthropic documents this as a breaking change for the Fable 5.1 generation ("forced tool
use returns an error"), with tool_choice: auto plus a prompt instruction as the
replacement.

Reproduction

Set CLAUDE_MODEL=claude-fable-5-1 (or claude-fable-5 for the silent variant) and ask
any question through the driver with the SQL tools loaded — e.g. the README's "What
companies are in the technology sector?". The failing request is the messages.create
call in src/core/driver.py (~line 516), which passes tool_choice={"type": "any"}.

Suggested fix

Drop tool_choice (the default is auto) and keep the existing system-prompt line that
already tells the model it MUST use the SQL tools — that is exactly the workaround
Anthropic's migration guide recommends.

Run records (every request/response, 5 runs per case per model) are public:
https://github.com/atilavahedian/upshift/blob/main/reports/fable-5-1-upgrade.md — the runs
were made with upshift, a tool I'm building that diffs agent behavior across model
versions; the records stand on their own.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions