From 8242f5bd1971e723064c05cdfc9a7b386628fa32 Mon Sep 17 00:00:00 2001 From: Shreehitha Arushan Date: Tue, 25 Aug 2026 15:57:18 +0530 Subject: [PATCH 1/5] fix(proxy): log warning instead of silently swallowing enterprise hooks ImportError --- litellm/proxy/hooks/__init__.py | 13 ++++--- .../proxy/hooks/test_proxy_hooks_init.py | 35 +++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/litellm/proxy/hooks/__init__.py b/litellm/proxy/hooks/__init__.py index 8714dd5f3d2..ae856598736 100644 --- a/litellm/proxy/hooks/__init__.py +++ b/litellm/proxy/hooks/__init__.py @@ -11,6 +11,7 @@ from .parallel_request_limiter import _PROXY_MaxParallelRequestsHandler from .parallel_request_limiter_v3 import _PROXY_MaxParallelRequestsHandler_v3 from .responses_id_security import ResponsesIDSecurity from .sensitive_data_routing import _PROXY_SensitiveDataRoutingHandler +from litellm._logging import verbose_proxy_logger # List of all available hooks that can be enabled. # Defined before the enterprise import below so that any module re-imported @@ -47,10 +48,8 @@ def get_proxy_hook( try: from enterprise.enterprise_hooks import ENTERPRISE_PROXY_HOOKS -except ImportError: - ENTERPRISE_PROXY_HOOKS = {} - - -### update PROXY_HOOKS with ENTERPRISE_PROXY_HOOKS ### - -PROXY_HOOKS.update(ENTERPRISE_PROXY_HOOKS) + PROXY_HOOKS.update(ENTERPRISE_PROXY_HOOKS) +except ImportError as e: + verbose_proxy_logger.warning( + f"Could not import enterprise hooks — enterprise features disabled: {e}" + ) diff --git a/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py b/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py index a6edd3db944..df4dac7c201 100644 --- a/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py +++ b/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py @@ -49,3 +49,38 @@ def test_isolation_module_does_not_pull_in_proxy_utils(): importlib.import_module("litellm.llms.base_llm.managed_resources.isolation") assert "litellm.proxy.utils" not in sys.modules assert "litellm.proxy.management_endpoints.common_utils" not in sys.modules + +def test_enterprise_hooks_import_failure_logs_warning(monkeypatch, caplog): + """ + If the `enterprise` / `litellm_enterprise` package is unavailable + (e.g. missing from a hardened non_root Docker image), hooks/__init__.py + should log a warning and continue, instead of letting the ImportError + propagate and crash the whole proxy at import time. + """ + import builtins + import importlib + import logging + import sys + + real_import = builtins.__import__ + + def fake_import(name, *args, **kwargs): + if name == "enterprise" or name.startswith("enterprise."): + raise ImportError("No module named 'enterprise'") + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", fake_import) + sys.modules.pop("litellm.proxy.hooks", None) + + with caplog.at_level(logging.WARNING): + import litellm.proxy.hooks as hooks_module + importlib.reload(hooks_module) + + assert any( + "enterprise hooks" in record.message.lower() + for record in caplog.records + ), "Expected a warning to be logged when enterprise hooks import fails" + + monkeypatch.undo() + sys.modules.pop("litellm.proxy.hooks", None) + importlib.import_module("litellm.proxy.hooks") From 54c930d2cab32928df628b4ac1bef1081ba35cc3 Mon Sep 17 00:00:00 2001 From: Shreehitha Arushan <130902361+csarushan1729@users.noreply.github.com> Date: Tue, 25 Aug 2026 16:28:01 +0530 Subject: [PATCH 2/5] Update tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py b/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py index df4dac7c201..4753b5fdb9b 100644 --- a/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py +++ b/tests/test_litellm/proxy/hooks/test_proxy_hooks_init.py @@ -81,6 +81,6 @@ def test_enterprise_hooks_import_failure_logs_warning(monkeypatch, caplog): for record in caplog.records ), "Expected a warning to be logged when enterprise hooks import fails" - monkeypatch.undo() + monkeypatch.setattr(builtins, "__import__", real_import) sys.modules.pop("litellm.proxy.hooks", None) importlib.import_module("litellm.proxy.hooks") From 62ef01c6248358fb73a7b3a039765e0ad032f895 Mon Sep 17 00:00:00 2001 From: Shreehitha Arushan Date: Tue, 25 Aug 2026 16:33:10 +0530 Subject: [PATCH 3/5] fix(proxy): apply ruff format --- litellm/proxy/hooks/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/hooks/__init__.py b/litellm/proxy/hooks/__init__.py index ae856598736..e166706a00b 100644 --- a/litellm/proxy/hooks/__init__.py +++ b/litellm/proxy/hooks/__init__.py @@ -48,8 +48,7 @@ def get_proxy_hook( try: from enterprise.enterprise_hooks import ENTERPRISE_PROXY_HOOKS + PROXY_HOOKS.update(ENTERPRISE_PROXY_HOOKS) except ImportError as e: - verbose_proxy_logger.warning( - f"Could not import enterprise hooks — enterprise features disabled: {e}" - ) + verbose_proxy_logger.warning(f"Could not import enterprise hooks — enterprise features disabled: {e}") From fcb0ed35e5a8282c3cc407db036a04b9eb3fe29f Mon Sep 17 00:00:00 2001 From: Shreehitha Arushan Date: Tue, 25 Aug 2026 16:37:05 +0530 Subject: [PATCH 4/5] fix(proxy): sort imports per ruff isort rules --- litellm/proxy/hooks/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/hooks/__init__.py b/litellm/proxy/hooks/__init__.py index e166706a00b..e1e97bebed2 100644 --- a/litellm/proxy/hooks/__init__.py +++ b/litellm/proxy/hooks/__init__.py @@ -1,6 +1,8 @@ import os from typing import Final, Literal +from litellm._logging import verbose_proxy_logger + from . import * from .cache_control_check import _PROXY_CacheControlCheck from .litellm_skills import SkillsInjectionHook @@ -11,7 +13,6 @@ from .parallel_request_limiter import _PROXY_MaxParallelRequestsHandler from .parallel_request_limiter_v3 import _PROXY_MaxParallelRequestsHandler_v3 from .responses_id_security import ResponsesIDSecurity from .sensitive_data_routing import _PROXY_SensitiveDataRoutingHandler -from litellm._logging import verbose_proxy_logger # List of all available hooks that can be enabled. # Defined before the enterprise import below so that any module re-imported From 962acf4186b5db9ac7308e70df80d219db5a3b00 Mon Sep 17 00:00:00 2001 From: Shreehitha Arushan Date: Tue, 25 Aug 2026 16:50:31 +0530 Subject: [PATCH 5/5] fix(proxy): use lazy %-style logging per repo convention --- litellm/proxy/hooks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litellm/proxy/hooks/__init__.py b/litellm/proxy/hooks/__init__.py index e1e97bebed2..1ea843c86e5 100644 --- a/litellm/proxy/hooks/__init__.py +++ b/litellm/proxy/hooks/__init__.py @@ -52,4 +52,4 @@ try: PROXY_HOOKS.update(ENTERPRISE_PROXY_HOOKS) except ImportError as e: - verbose_proxy_logger.warning(f"Could not import enterprise hooks — enterprise features disabled: {e}") + verbose_proxy_logger.warning("Could not import enterprise hooks — enterprise features disabled: %s", e)