From b42ef469cfb3a87096c455e446bed4d4ff5dd43e Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:48:35 -0700 Subject: [PATCH] fix(policy_engine): warn that the config-defined policy reactivates when all DB versions are deleted --- litellm/proxy/policy_engine/policy_registry.py | 12 ++++++++++-- .../proxy/policy_engine/test_policy_versioning.py | 14 +++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/policy_engine/policy_registry.py b/litellm/proxy/policy_engine/policy_registry.py index 7d2b439270a..01b88836387 100644 --- a/litellm/proxy/policy_engine/policy_registry.py +++ b/litellm/proxy/policy_engine/policy_registry.py @@ -1031,12 +1031,20 @@ class PolicyRegistry: prisma_client: The Prisma client instance Returns: - Dict with success message + Dict with "message" and optional "warning" if a config-defined policy took over. """ try: await _policy_table(prisma_client).delete_many(where={"policy_name": policy_name}) self.remove_policy(policy_name) - return {"message": f"All versions of policy '{policy_name}' deleted successfully"} + message = f"All versions of policy '{policy_name}' deleted successfully" + if self.get_source(policy_name) == "config": + return { + "message": message, + "warning": ( + "All DB versions were deleted. The config-defined policy with the same name is active again." + ), + } + return {"message": message} except Exception as e: verbose_proxy_logger.exception(f"Error deleting all versions: {e}") raise Exception(f"Error deleting all versions: {str(e)}") diff --git a/tests/test_litellm/proxy/policy_engine/test_policy_versioning.py b/tests/test_litellm/proxy/policy_engine/test_policy_versioning.py index 41d856e7baf..ebebfde5cd3 100644 --- a/tests/test_litellm/proxy/policy_engine/test_policy_versioning.py +++ b/tests/test_litellm/proxy/policy_engine/test_policy_versioning.py @@ -613,9 +613,21 @@ class TestRemovePolicyRestoresConfigFallback: prisma = MagicMock() prisma.db.litellm_policytable.delete_many = AsyncMock() - await registry.delete_all_versions(policy_name="shared-name", prisma_client=prisma) + result = await registry.delete_all_versions(policy_name="shared-name", prisma_client=prisma) assert registry.get_source("shared-name") == "config" policy = registry.get_policy("shared-name") assert policy is not None assert policy.guardrails.add == ["config-guard"] + assert "config" in result["warning"] + + async def test_delete_all_versions_without_config_twin_has_no_warning(self): + registry = PolicyRegistry() + registry.add_policy("db-only", Policy(guardrails=PolicyGuardrails(add=["db-guard"])), source="db") + prisma = MagicMock() + prisma.db.litellm_policytable.delete_many = AsyncMock() + + result = await registry.delete_all_versions(policy_name="db-only", prisma_client=prisma) + + assert registry.get_policy("db-only") is None + assert "warning" not in result