{"record":{"id":"935e77d26f991ac4","repo":"BerriAI/litellm","slug":"exactly-one-of-model-id-or-model-name-must-be-prov","errorCode":null,"errorMessage":"Exactly one of model_id or model_name must be provided","messagePattern":"Exactly one of model_id or model_name must be provided","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/client/models.py","lineNumber":178,"sourceCode":"        Get information about a specific model by its ID or name.\n\n        Args:\n            model_id (Optional[str]): ID of the model to retrieve\n            model_name (Optional[str]): Name of the model to retrieve\n            return_request (bool): If True, returns the prepared request object instead of executing it\n\n        Returns:\n            Union[Dict[str, Any], requests.Request]: Either the model information from the server or\n            a prepared request object if return_request is True\n\n        Raises:\n            ValueError: If neither model_id nor model_name is provided, or if both are provided\n            UnauthorizedError: If the request fails with a 401 status code\n            NotFoundError: If the model is not found\n            requests.exceptions.RequestException: If the request fails with any other error\n        \"\"\"\n        if (model_id is None and model_name is None) or (model_id is not None and model_name is not None):\n            raise ValueError(\"Exactly one of model_id or model_name must be provided\")\n\n        # If return_request is True, delegate to info\n        if return_request:\n            result: Final = self.info(return_request=True)\n            assert isinstance(result, requests.Request)\n            return result\n\n        # Get all models and filter\n        models: Final = self.info()\n        assert isinstance(models, list)\n\n        # Find the matching model\n        for model in models:\n            if (model_id and model.get(\"model_info\", {}).get(\"id\") == model_id) or (\n                model_name and model.get(\"model_name\") == model_name\n            ):\n                return model\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/client/models.py#L160-L196","documentation":"Client-side guard inside ModelsManagementClient.get(): the method requires exactly one of model_id / model_name, and passing neither or both raises ValueError('Exactly one of model_id or model_name must be provided') before any network call. get() then downloads the full /v1/model/info list and filters locally by the single identifier you gave, which is why the arguments are mutually exclusive. This is a pure programming error in the caller, not a server condition.","triggerScenarios":"Calling get() with no arguments; calling get(model_id=_id, model_name=name) when both variables are populated; forwarding optional kwargs from your own wrapper into get() without normalizing absent values to None; refactor renaming one parameter so callers accidentally set both.","commonSituations":"Wrapper APIs that accept optional model_id and model_name and pass them straight through; dynamic callers building kwargs dicts that end up empty; copy-pasted calls carrying leftover arguments.","solutions":["Pass exactly one identifier: models.get(model_id='2f23364f-...') or models.get(model_name='gpt-4o-mini')","Normalize optional kwargs to None (and drop them) before calling so the guard sees exactly one","If you somehow hold both, prefer model_id — UUIDs are exact matches, names can collide"],"exampleFix":"# before\nmodel = client.models.get(model_id=None, model_name=None)  # ValueError\n\n# after\nmodel = (\n    client.models.get(model_id=model_id)\n    if model_id is not None\n    else client.models.get(model_name=model_name)\n)","handlingStrategy":"validation","validationCode":"def get_model_kwargs(model_id: str | None, model_name: str | None) -> dict:\n    if (model_id is None) == (model_name is None):\n        raise ValueError(\"pass exactly one of model_id / model_name\")\n    return {\"model_id\": model_id} if model_id is not None else {\"model_name\": model_name}\n\n# models.get(**get_model_kwargs(model_id, model_name))","typeGuard":"from typing import Any\n\ndef is_valid_get_args(model_id: Any, model_name: Any) -> bool:\n    return (model_id is None) != (model_name is None)  # exactly one set","tryCatchPattern":"try:\n    model = models.get(model_id=model_id, model_name=model_name)\nexcept ValueError as e:\n    if \"Exactly one\" in str(e):\n        model = models.get(**get_model_kwargs(model_id, model_name))  # normalize and retry\n    else:\n        raise","preventionTips":["Normalize optional identifiers to None and drop empty strings before calling get()","Wrap the call with a one-argument helper so the invariant is enforced in one place","Remember get() filters locally over /v1/model/info — an empty-string id won't raise here but will 404-match nothing"],"tags":["litellm","validation","python","client-side","models"],"backgroundTag":"invalid-argument","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}