{"record":{"id":"eda78ccd394196f3","repo":"BerriAI/litellm","slug":"model-is-required-eda78c","errorCode":null,"errorMessage":"model is required","messagePattern":"model is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/endpoints/speech/speech_to_completion_bridge/handler.py","lineNumber":37,"sourceCode":"    litellm_params: dict\n    logging_obj: \"LiteLLMLoggingObj\"\n    headers: dict\n    custom_llm_provider: str\n\n\nclass SpeechToCompletionBridgeHandler:\n    def __init__(self):\n        from .transformation import SpeechToCompletionBridgeTransformationHandler\n\n        super().__init__()\n        self.transformation_handler = SpeechToCompletionBridgeTransformationHandler()\n\n    def validate_input_kwargs(self, kwargs: dict) -> SpeechToCompletionBridgeHandlerInputKwargs:\n        from litellm import LiteLLMLoggingObj\n\n        model: Final = kwargs.get(\"model\")\n        if model is None or not isinstance(model, str):\n            raise ValueError(\"model is required\")\n\n        custom_llm_provider: Final = kwargs.get(\"custom_llm_provider\")\n        if custom_llm_provider is None or not isinstance(custom_llm_provider, str):\n            raise ValueError(\"custom_llm_provider is required\")\n\n        input: Final = kwargs.get(\"input\")\n        if input is None or not isinstance(input, str):\n            raise ValueError(\"input is required\")\n\n        optional_params: Final = kwargs.get(\"optional_params\")\n        if optional_params is None or not isinstance(optional_params, dict):\n            raise ValueError(\"optional_params is required\")\n\n        litellm_params: Final = kwargs.get(\"litellm_params\")\n        if litellm_params is None or not isinstance(litellm_params, dict):\n            raise ValueError(\"litellm_params is required\")\n\n        headers = kwargs.get(\"headers\")","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/endpoints/speech/speech_to_completion_bridge/handler.py#L19-L55","documentation":"Thrown by SpeechToCompletionBridgeHandler.validate_input_kwargs when the internal kwargs dict has no 'model' key or its value is not a str. This handler bridges /audio/speech (TTS) calls to chat/completions models (e.g. gpt-4o-audio-preview), and validates the assembled kwargs in litellm/endpoints/speech/speech_to_completion_bridge/handler.py:37. It indicates the speech() entrypoint was called without a usable model string, which normally only happens when routing/internal plumbing passes an empty model through.","triggerScenarios":"Calling litellm.speech()/audio_speech routed through the speech_to_completion_bridge with model=None, model missing from the request, or model set to a non-string (e.g. a dict or int). Also reachable if custom router code invokes speech_to_completion_bridge_handler.speech(...) directly without a model argument.","commonSituations":"Proxy config or router code that forwards a malformed body to the /v1/audio/speech endpoint; passing a deployment object instead of the model name string; programmatic calls that build kwargs dynamically and omit 'model'.","solutions":["Pass a valid non-empty model string (e.g. 'gpt-4o-audio-preview') to the speech/TTS call","If calling the handler directly, include model= in the kwargs passed to speech_to_completion_bridge_handler.speech()","On the LiteLLM proxy, verify the request body to /v1/audio/speech contains a string 'model' field before routing"],"exampleFix":"# before\nresp = litellm.audio_speech(model=None, input=\"hello\", voice=\"alloy\")\n\n# after\nresp = litellm.audio_speech(model=\"gpt-4o-audio-preview\", input=\"hello\", voice=\"alloy\")","handlingStrategy":"validation","validationCode":"def validate_speech_call(model, input_text, **kwargs):\n    if not isinstance(model, str) or not model.strip():\n        raise ValueError(\"model must be a non-empty string\")\n    if not isinstance(input_text, str):\n        raise ValueError(\"input must be a string\")\n\nvalidate_speech_call(model, text)","typeGuard":"def is_valid_speech_model(model: object) -> bool:\n    return isinstance(model, str) and len(model.strip()) > 0","tryCatchPattern":"try:\n    resp = litellm.audio_speech(model=model, input=text, voice=voice)\nexcept ValueError as e:\n    if \"model is required\" in str(e):\n        logger.error(\"TTS call missing model; check request body\")\n        raise","preventionTips":["Always pass an explicit literal model string to speech/TTS calls","Validate request payloads at the API boundary before forwarding to litellm","Type-annotate call sites so None model values fail static checks"],"tags":["validation","tts","speech","model","input-validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}