BerriAI/litellm · error · BadRequestError

Exception - Use 'watsonx_text' route instead. IBM WatsonX…

Error message

{custom_llm_provider.capitalize()}Exception - Use 'watsonx_text' route instead. IBM WatsonX does not support `/text/chat` endpoint. - {error_str}

What it means

When an OpenAI-like provider error contains 'model_no_support_for_function' - IBM watsonx rejecting a tools/functions request on the /text/chat path - litellm raises BadRequestError with explicit guidance: use the 'watsonx_text' route instead, because IBM WatsonX does not support the /text/chat endpoint for that call. This is litellm routing you to a code path that can carry the request, not a transient failure.

Solutions

  1. Switch the model prefix to the watsonx_text route (model="watsonx_text/<model_id>") so the request hits the supported endpoint
  2. If tools are optional, drop tools=/functions= and parse structured output from plain text instead
  3. Use a watsonx model/version with native function-calling support
  4. After a litellm upgrade, re-check the watsonx routing docs for current route names

Example fix

# before - tools through a route that rejects them
resp = litellm.completion(
    model="watsonx/<model_id>",
    messages=msgs,
    tools=[{"type": "function", "function": {"name": "get_weather", "parameters": {...}}}],
)

# after - same model via the supported route
resp = litellm.completion(
    model="watsonx_text/<model_id>",
    messages=msgs,
    tools=[{"type": "function", "function": {"name": "get_weather", "parameters": {...}}}],
)
Defensive patterns

Strategy: fallback

Validate before calling

def resolve_watsonx_model(model: str, tools: list | None) -> str:
    """Send tool-calling traffic down the supported watsonx route."""
    if tools and model.startswith("watsonx/") and not model.startswith("watsonx_text/"):
        return model.replace("watsonx/", "watsonx_text/", 1)
    return model

Type guard

import litellm

def is_watsonx_route_error(exc: BaseException) -> bool:
    return (
        isinstance(exc, litellm.BadRequestError)
        and "watsonx_text" in getattr(exc, "message", "")
    )

Try / catch

try:
    resp = litellm.completion(model=model, messages=messages, tools=tools)
except litellm.BadRequestError as e:
    if "watsonx_text" in e.message and model.startswith("watsonx/"):
        # retry once on the supported route
        resp = litellm.completion(
            model=model.replace("watsonx/", "watsonx_text/", 1),
            messages=messages,
            tools=tools,
        )
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm.completion with tools=/functions=/tool_choice= against a watsonx model through a route whose endpoint refuses function payloads; mixing OpenAI-style tool schemas into a watsonx chat-route call.

Common situations: Porting an OpenAI tool-calling app to watsonx unchanged; enabling tools on a granite model via the chat route; provider-side route changes after a litellm upgrade.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/fe7737f652b57489. Report an issue: GitHub.

Appendix: source

Thrown at litellm/litellm_core_utils/exception_mapping_utils.py:746

            llm_provider=custom_llm_provider,
            response=getattr(original_exception, "response", None),
            litellm_debug_info=extra_information,
        )
    elif "token_quota_reached" in error_str:
        raise RateLimitError(
            message=f"{custom_llm_provider.capitalize()}Exception: Rate Limit Errror - {error_str}",
            llm_provider=custom_llm_provider,
            model=model,
            response=getattr(original_exception, "response", None),
        )
    elif "The server received an invalid response from an upstream server." in error_str:
        raise litellm.InternalServerError(
            message=f"{custom_llm_provider.capitalize()}Exception - {original_exception.message}",
            llm_provider=custom_llm_provider,
            model=model,
        )
    elif "model_no_support_for_function" in error_str:
        raise BadRequestError(
            message=f"{custom_llm_provider.capitalize()}Exception - Use 'watsonx_text' route instead. IBM WatsonX does not support `/text/chat` endpoint. - {error_str}",
            llm_provider=custom_llm_provider,
            model=model,
        )
    elif hasattr(original_exception, "status_code"):
        if original_exception.status_code == 500:
            raise litellm.InternalServerError(
                message=f"{custom_llm_provider.capitalize()}Exception - {original_exception.message}",
                llm_provider=custom_llm_provider,
                model=model,
            )
        elif original_exception.status_code == 401 or original_exception.status_code == 403:
            raise AuthenticationError(
                message=f"{custom_llm_provider.capitalize()}Exception - {original_exception.message}",
                llm_provider=custom_llm_provider,
                model=model,
            )
        elif original_exception.status_code == 400:

View on GitHub (pinned to 77b7c6c40c)