From f1ec7a5753fc4e5ce237302535c17b3781e1c788 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 00:01:53 +0000 Subject: [PATCH] refactor(sso): avoid recursion in get_litellm_user_role Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/proxy/management_endpoints/types.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/litellm/proxy/management_endpoints/types.py b/litellm/proxy/management_endpoints/types.py index 21d5d491adc..c40fe03a474 100644 --- a/litellm/proxy/management_endpoints/types.py +++ b/litellm/proxy/management_endpoints/types.py @@ -34,6 +34,13 @@ def highest_privilege_role(roles: Sequence[LitellmUserRoles]) -> LitellmUserRole return roles[0] if roles else None +def _lookup_role(role_str: object) -> LitellmUserRoles | None: + if not isinstance(role_str, str): + return None + result: Final = LitellmUserRoles._value2member_map_.get(role_str.lower()) + return cast(LitellmUserRoles | None, result) + + def is_valid_litellm_user_role(role_str: str) -> bool: """ Check if a string is a valid LitellmUserRoles enum value (case-insensitive). @@ -69,11 +76,9 @@ def get_litellm_user_role(role_str) -> LitellmUserRoles | None: if isinstance(role_str, list): entries: Final[Sequence[object]] = role_str return highest_privilege_role( - tuple(role for role in (get_litellm_user_role(entry) for entry in entries) if role is not None) + tuple(role for role in (_lookup_role(entry) for entry in entries) if role is not None) ) - # Use _value2member_map_ for O(1) lookup, case-insensitive - result: Final = LitellmUserRoles._value2member_map_.get(role_str.lower()) - return cast(LitellmUserRoles | None, result) + return _lookup_role(role_str) except Exception: return None