sgl-project/sglang · error · ValueError

tool_choice references tool {tool_name!r} but it is not in t

Error message

tool_choice references tool {tool_name!r} but it is not in the forwarded tools list (server-side Anthropic tools cannot be selected)

What it means

Raised during Anthropic-to-OpenAI-compatible request conversion when tool_choice names a specific tool (type='tool' with a name, or the legacy 'function' form) that is not present in the request's tools list. SGLang only forwards client-supplied custom tools to the backend; server-side Anthropic built-in tools (web_search, code_execution, etc.) cannot be selected, so an unmatched name is a 400.

Source

Thrown at python/sglang/srt/entrypoints/anthropic/serving.py:714

        if anthropic_request.tool_choice is not None:
            tc_type = anthropic_request.tool_choice.type
            if tc_type == "none":
                chat_request.tool_choice = "none"
            elif chat_request.tools:
                if tc_type == "auto":
                    chat_request.tool_choice = "auto"
                elif tc_type == "any":
                    chat_request.tool_choice = "required"
                elif tc_type == "tool":
                    tool_name = anthropic_request.tool_choice.name
                    # ``Tool.function`` is a ``Function`` Pydantic model, not
                    # a dict — access by attribute. A dict ``.get`` would
                    # AttributeError and surface as a 500 instead of the
                    # intended 400 / happy path.
                    if not any(
                        t.function.name == tool_name for t in chat_request.tools
                    ):
                        raise ValueError(
                            f"tool_choice references tool {tool_name!r} but it "
                            f"is not in the forwarded tools list "
                            f"(server-side Anthropic tools cannot be selected)"
                        )
                    chat_request.tool_choice = ToolChoice(
                        type="function",
                        function=ToolChoiceFuncName(name=tool_name),
                    )
            elif tc_type in ("any", "tool"):
                raise ValueError(
                    f"tool_choice={tc_type!r} requires at least one custom "
                    f"tool; all supplied tools were server-side Anthropic "
                    f"built-ins which the OpenAI-compatible backend cannot "
                    f"invoke"
                )
        elif chat_request.tools:
            chat_request.tool_choice = "auto"

View on GitHub (pinned to 0132848349)

Solutions

  1. Make tool_choice.name exactly match a tool's name field in the same request's tools array
  2. Do not reference server-side Anthropic built-in tools in tool_choice — define a custom tool instead
  3. Use tool_choice type 'auto' if you don't need to force a specific tool

Example fix

// before
{"tools": [{"name": "get_weather", ...}], "tool_choice": {"type": "tool", "name": "GetWeather"}}
// after
{"tools": [{"name": "get_weather", ...}], "tool_choice": {"type": "tool", "name": "get_weather"}}
Defensive patterns

Strategy: validation

Validate before calling

names = {t.get("name") for t in tools if t.get("type") in ("custom", "function")}
if tool_choice.get("type") == "tool" and tool_choice.get("name") not in names:
    raise ValueError("tool_choice.name must match a custom tool name")

Type guard

def tool_choice_is_valid(tool_choice, tools) -> bool:
    if tool_choice.get("type") != "tool": return True
    return tool_choice.get("name") in {t.get("name") for t in tools}

Try / catch

try: resp = client.messages.create(...)
except ValueError as e:
    if 'tool_choice references tool' in str(e): fix_name_and_retry()

Prevention

When it happens

Trigger: POST /v1/messages with tool_choice={"type": "tool", "name": "get_weather"} where no tool named get_weather appears in the tools array; or tool_choice naming an Anthropic built-in like web_search_20250305.

Common situations: Typos or case mismatches between tool name and tool_choice name; assuming built-in Anthropic tools can be force-selected; frontend and backend tool definitions drifting out of sync.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/a285f074cb096dfc. Report an issue: GitHub.