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
- Switch the model prefix to the watsonx_text route (model="watsonx_text/<model_id>") so the request hits the supported endpoint
- If tools are optional, drop tools=/functions= and parse structured output from plain text instead
- Use a watsonx model/version with native function-calling support
- 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
- Centralize model-string selection so route prefixes are correct everywhere
- Integration-test tool-calling once per provider at onboarding
- Watch litellm release notes for watsonx route changes
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
- API key is required
- BFL initial request failed
- Exception: Context Window Error
- Error transforming response to json
- Error: Watsonx API base not set. Set WATSONX_API_BASE in…
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)