{"record":{"id":"fe7737f652b57489","repo":"BerriAI/litellm","slug":"custom-llm-provider-capitalize-exception-use","errorCode":null,"errorMessage":"{custom_llm_provider.capitalize()}Exception - Use 'watsonx_text' route instead. IBM WatsonX does not support `/text/chat` endpoint. - {error_str}","messagePattern":"(.+?)Exception - Use 'watsonx_text' route instead\\. IBM WatsonX does not support `/text/chat` endpoint\\. - (.+?)","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"litellm/litellm_core_utils/exception_mapping_utils.py","lineNumber":746,"sourceCode":"            llm_provider=custom_llm_provider,\n            response=getattr(original_exception, \"response\", None),\n            litellm_debug_info=extra_information,\n        )\n    elif \"token_quota_reached\" in error_str:\n        raise RateLimitError(\n            message=f\"{custom_llm_provider.capitalize()}Exception: Rate Limit Errror - {error_str}\",\n            llm_provider=custom_llm_provider,\n            model=model,\n            response=getattr(original_exception, \"response\", None),\n        )\n    elif \"The server received an invalid response from an upstream server.\" in error_str:\n        raise litellm.InternalServerError(\n            message=f\"{custom_llm_provider.capitalize()}Exception - {original_exception.message}\",\n            llm_provider=custom_llm_provider,\n            model=model,\n        )\n    elif \"model_no_support_for_function\" in error_str:\n        raise BadRequestError(\n            message=f\"{custom_llm_provider.capitalize()}Exception - Use 'watsonx_text' route instead. IBM WatsonX does not support `/text/chat` endpoint. - {error_str}\",\n            llm_provider=custom_llm_provider,\n            model=model,\n        )\n    elif hasattr(original_exception, \"status_code\"):\n        if original_exception.status_code == 500:\n            raise litellm.InternalServerError(\n                message=f\"{custom_llm_provider.capitalize()}Exception - {original_exception.message}\",\n                llm_provider=custom_llm_provider,\n                model=model,\n            )\n        elif original_exception.status_code == 401 or original_exception.status_code == 403:\n            raise AuthenticationError(\n                message=f\"{custom_llm_provider.capitalize()}Exception - {original_exception.message}\",\n                llm_provider=custom_llm_provider,\n                model=model,\n            )\n        elif original_exception.status_code == 400:","sourceCodeStart":728,"sourceCodeEnd":764,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/exception_mapping_utils.py#L728-L764","documentation":"Raised as BadRequestError when the provider error string contains 'model_no_support_for_function'. The message is hard-coded to talk about the watsonx 'watsonx_text' route, which is misleading: this fires for ANY provider whose error mentions that token, not just watsonx. The underlying problem is you passed tools/functions to a model or endpoint that does not support function calling.","triggerScenarios":"Calling litellm.completion(..., tools=[...]) against a model or endpoint without function-calling support — classically the watsonx '/text/chat' endpoint instead of the 'watsonx_text' route, or a base model served behind a gateway that rejects the tools parameter.","commonSituations":"Using IBM watsonx with the wrong model string (chat-tuned vs base text endpoint), pointing a tools-enabled agent at a completion-only or base model, or a gateway stripping/forbidding the tools field.","solutions":["For watsonx: change the model string to use the 'watsonx_text' route (e.g. 'watsonx/ibm/granite-...' via the text route) instead of '/text/chat'.","Check litellm.get_model_info(model).get('supports_function_calling') before sending tools.","Drop the tools/functions parameter if the model cannot use them, and parse structured output from plain text instead.","Switch to a model that supports function calling (gpt-4o, claude, mistral function-call variants)."],"exampleFix":"# before\nresp = litellm.completion(model=\"watsonx/google/flan-t5-xl\", messages=msgs, tools=tools)\n\n# after\ninfo = litellm.get_model_info(\"watsonx/google/flan-t5-xl\")\nif not info.get(\"supports_function_calling\"):\n    resp = litellm.completion(model=\"watsonx/google/flan-t5-xl\", messages=msgs)  # no tools\nelse:\n    resp = litellm.completion(model=\"watsonx/google/flan-t5-xl\", messages=msgs, tools=tools)","handlingStrategy":"validation","validationCode":"import litellm\n\ndef supports_tools(model: str) -> bool:\n    try:\n        return bool(litellm.get_model_info(model).get(\"supports_function_calling\", False))\n    except Exception:\n        return False","typeGuard":"import litellm\n\ndef is_no_function_support(e: BaseException) -> bool:\n    return isinstance(e, litellm.BadRequestError) and \"model_no_support_for_function\" in str(e)","tryCatchPattern":"try:\n    resp = litellm.completion(model=m, messages=msgs, tools=tools)\nexcept litellm.BadRequestError as e:\n    if \"model_no_support_for_function\" in str(e):\n        resp = litellm.completion(model=m, messages=msgs)  # retry without tools\n    else:\n        raise","preventionTips":["Check get_model_info(model)['supports_function_calling'] before passing tools.","Do not assume watsonx from the message text — the message is hard-coded and fires for any provider.","For watsonx, use the 'watsonx_text' route model strings."],"tags":["function-calling","watsonx","bad-request","litellm"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}