{"record":{"id":"11e182df4c4a457b","repo":"BerriAI/litellm","slug":"custom-llm-provider-is-required","errorCode":null,"errorMessage":"custom_llm_provider is required","messagePattern":"custom_llm_provider is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/completion_extras/litellm_responses_transformation/handler.py","lineNumber":114,"sourceCode":"        hidden_params: Final = getattr(stream_iter, \"_hidden_params\", None)\n        response: Final = self._coerce_response_object(response_obj, hidden_params)\n        if not isinstance(response, ResponsesAPIResponse):\n            raise ValueError(\"Stream completed response is invalid\")\n        return response\n\n    def validate_input_kwargs(self, kwargs: dict) -> ResponsesToCompletionBridgeHandlerInputKwargs:\n        from litellm import LiteLLMLoggingObj\n        from litellm.types.utils import ModelResponse\n\n        typed_kwargs: Final[dict[str, object]] = kwargs\n\n        model: Final = typed_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 = typed_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        messages: Final = typed_kwargs.get(\"messages\")\n        if messages is None or not isinstance(messages, list):\n            raise ValueError(\"messages is required\")\n\n        optional_params: Final = typed_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 = typed_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: Final = typed_kwargs.get(\"headers\")\n        if headers is None or not isinstance(headers, dict):\n            raise ValueError(\"headers is required\")\n\n        model_response: Final = typed_kwargs.get(\"model_response\")","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/completion_extras/litellm_responses_transformation/handler.py#L96-L132","documentation":"validate_input_kwargs raises when the kwargs dict lacks 'custom_llm_provider' or it is not a str. The bridge handler needs the resolved provider name to route the transformed Responses API call. Like the other kwargs checks in this method, it fires only when the handler is invoked with an incomplete hand-built kwargs dict rather than through litellm.completion.","triggerScenarios":"Direct invocation of ResponsesToCompletionBridgeHandler.validate_input_kwargs / async_completion with kwargs missing custom_llm_provider (e.g. only model and messages supplied).","commonSituations":"Custom routing layers that build the kwargs dict themselves; tests stubbing the completion pipeline; upgrading litellm where the internal kwargs contract changed.","solutions":["Use litellm.completion(model=\"provider/model\", ...) so the provider is resolved and passed automatically","If calling directly, set custom_llm_provider to the resolved provider string (e.g. \"openai\", \"azure\") in kwargs","Verify you are not passing the kwargs from get_optional_params directly without provider resolution"],"exampleFix":"# before\nkwargs = {\"model\": \"gpt-4o\", \"messages\": msgs}\n\n# after\nkwargs = {\n    \"model\": \"gpt-4o\",\n    \"custom_llm_provider\": \"openai\",\n    \"messages\": msgs,\n    # ...remaining required keys per handler.py:16\n}","handlingStrategy":"validation","validationCode":"def has_provider_kwarg(kwargs: dict) -> bool:\n    return isinstance(kwargs.get(\"custom_llm_provider\"), str) and bool(kwargs[\"custom_llm_provider\"])","typeGuard":"def is_valid_bridge_kwargs(kwargs: dict) -> bool:\n    return isinstance(kwargs.get(\"custom_llm_provider\"), str)","tryCatchPattern":null,"preventionTips":["Let litellm resolve the provider via the model string (\"openai/gpt-4o\")","Validate the kwargs contract in one helper before calling the handler","Keep a single construction site for bridge kwargs in your codebase"],"tags":["validation","bridge","internal-api","provider-resolution"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}