fix(router.py): use more descriptive error message (#12629)

* fix(router.py): use more descriptive error message

* fix(proxy/_types.py): note `/team/member_update` is a self-managed route

route has it's own logic for rbac - enables team admins to update member permissions

Fixes issue where team admins on UI could not update member permissions

* fix(token_counter.py): move log line to being '.debug' instead of '.error'

Fixes https://github.com/BerriAI/litellm/issues/12269
This commit is contained in:
Krish Dholakia
2025-07-15 22:34:20 -07:00
committed by GitHub
parent 85fe1d35e1
commit 3ad4d9fc3e
4 changed files with 52 additions and 16 deletions
+1 -1
View File
@@ -98,7 +98,7 @@ def get_modified_max_tokens(
return user_max_tokens
except Exception as e:
verbose_logger.error(
verbose_logger.debug(
"litellm.litellm_core_utils.token_counter.py::get_modified_max_tokens() - Error while checking max token limit: {}\nmodel={}, base_model={}".format(
str(e), model, base_model
)
+18 -12
View File
@@ -499,6 +499,7 @@ class LiteLLMRoutes(enum.Enum):
self_managed_routes = [
"/team/member_add",
"/team/member_delete",
"/team/member_update",
"/team/permissions_list",
"/team/permissions_update",
"/team/daily/activity",
@@ -562,14 +563,16 @@ class LiteLLMPromptInjectionParams(LiteLLMPydanticObjectBase):
)
return values
######### Request Class Definition ######
class ProxyChatCompletionRequest(ChatCompletionRequest):
# Optional LiteLLM params
guardrails: Optional[List[str]]
caching: Optional[bool]
num_retries: Optional[int]
context_window_fallback_dict: Optional[Dict[str, str]]
fallbacks: Optional[List[str]]
guardrails: Optional[List[str]]
caching: Optional[bool]
num_retries: Optional[int]
context_window_fallback_dict: Optional[Dict[str, str]]
fallbacks: Optional[List[str]]
class ModelInfoDelete(LiteLLMPydanticObjectBase):
id: str
@@ -828,7 +831,7 @@ class NewMCPServerRequest(LiteLLMPydanticObjectBase):
command: Optional[str] = None
args: List[str] = Field(default_factory=list)
env: Dict[str, str] = Field(default_factory=dict)
@model_validator(mode="before")
@classmethod
def validate_transport_fields(cls, values):
@@ -845,7 +848,6 @@ class NewMCPServerRequest(LiteLLMPydanticObjectBase):
return values
class UpdateMCPServerRequest(LiteLLMPydanticObjectBase):
server_id: str
alias: Optional[str] = None
@@ -860,7 +862,7 @@ class UpdateMCPServerRequest(LiteLLMPydanticObjectBase):
command: Optional[str] = None
args: List[str] = Field(default_factory=list)
env: Dict[str, str] = Field(default_factory=dict)
@model_validator(mode="before")
@classmethod
def validate_transport_fields(cls, values):
@@ -877,7 +879,6 @@ class UpdateMCPServerRequest(LiteLLMPydanticObjectBase):
return values
class LiteLLM_MCPServerTable(LiteLLMPydanticObjectBase):
"""Represents a LiteLLM_MCPServerTable record"""
@@ -1736,11 +1737,15 @@ class UserAPIKeyAuth(
@classmethod
def check_api_key(cls, values):
if values.get("api_key") is not None:
values.update({"token": cls._safe_hash_litellm_api_key(values.get("api_key"))})
values.update(
{"token": cls._safe_hash_litellm_api_key(values.get("api_key"))}
)
if isinstance(values.get("api_key"), str):
values.update({"api_key": cls._safe_hash_litellm_api_key(values.get("api_key"))})
values.update(
{"api_key": cls._safe_hash_litellm_api_key(values.get("api_key"))}
)
return values
@classmethod
def _safe_hash_litellm_api_key(cls, api_key: str) -> str:
"""
@@ -1752,6 +1757,7 @@ class UserAPIKeyAuth(
if api_key.startswith("sk-"):
return hash_token(api_key)
from litellm.proxy.auth.handle_jwt import JWTHandler
if JWTHandler.is_jwt(token=api_key):
return f"hashed-jwt-{hash_token(token=api_key)}"
return api_key
+10 -3
View File
@@ -6235,10 +6235,17 @@ class Router:
)
if len(healthy_deployments) == 0:
raise litellm.BadRequestError(
message="You passed in model={}. There is no 'model_name' with this string ".format(
if self.get_model_list(model_name=model) is None:
message = f"You passed in model={model}. There is no 'model_name' with this string".format(
model
),
)
else:
message = f"You passed in model={model}. There are no healthy deployments for this model".format(
model
)
raise litellm.BadRequestError(
message=message,
model=model,
llm_provider="",
)
+23
View File
@@ -2144,6 +2144,29 @@ def test_bedrock_application_inference_profile():
assert result is True
def test_image_response_utils():
"""Test that the image response utils are correct."""
from litellm.utils import ImageResponse
result = {
"created": None,
"data": [
{
"b64_json": "/9j/.../2Q==",
"revised_prompt": None,
"url": None,
"timings": {"inference": 0.9612685777246952},
"index": 0,
}
],
"id": "91559891cxxx-PDX",
"model": "black-forest-labs/FLUX.1-schnell-Free",
"object": "list",
"hidden_params": {"additional_headers": {}},
}
image_response = ImageResponse(**result)
if __name__ == "__main__":
# Allow running this test file directly for debugging
pytest.main([__file__, "-v"])