diff --git a/litellm/proxy/_experimental/out/virtual-keys/index.html b/litellm/proxy/_experimental/out/virtual-keys/index.html
new file mode 100644
index 00000000000..10ea404151e
--- /dev/null
+++ b/litellm/proxy/_experimental/out/virtual-keys/index.html
@@ -0,0 +1 @@
+
LiteLLM DashboardLoading...
\ No newline at end of file
diff --git a/litellm/proxy/guardrails/guardrail_hooks/cato_networks/cato_networks.py b/litellm/proxy/guardrails/guardrail_hooks/cato_networks/cato_networks.py
index 3ec1d00964d..3d61eec4fff 100644
--- a/litellm/proxy/guardrails/guardrail_hooks/cato_networks/cato_networks.py
+++ b/litellm/proxy/guardrails/guardrail_hooks/cato_networks/cato_networks.py
@@ -281,12 +281,13 @@ class CatoNetworksGuardrail(CustomGuardrail):
status_code=400,
detail=cato_output_guardrail_result.get("detection_message"),
)
- if cato_output_guardrail_result and cato_output_guardrail_result.get(
- "redacted_output"
- ):
- choice.message.content = cato_output_guardrail_result.get(
- "redacted_output"
- )
+ redacted_output = (
+ cato_output_guardrail_result.get("redacted_output")
+ if cato_output_guardrail_result
+ else None
+ )
+ if redacted_output is not None:
+ choice.message.content = redacted_output
return response
async def async_post_call_streaming_iterator_hook(
diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_cato_networks.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_cato_networks.py
index 517c05c0ade..80d0fac3ac1 100644
--- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_cato_networks.py
+++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_cato_networks.py
@@ -665,6 +665,44 @@ async def test_post_call_success_hook_anonymize_action_redacts_content():
assert result.choices[0].message.content == "Hello [NAME_1]"
+@pytest.mark.asyncio
+async def test_post_call_success_hook_anonymize_action_applies_empty_redacted_output():
+ guard = _make_guardrail()
+ request_data = {"messages": [{"role": "user", "content": "hi"}]}
+ anonymize_response = _make_response(
+ {
+ "analysis_result": {"policy_drill_down": {"PII": {}}},
+ "required_action": {"action_type": "anonymize_action", "policy_name": "PII"},
+ "redacted_chat": {
+ "all_redacted_messages": [
+ {"role": "user", "content": "hi"},
+ {"role": "assistant", "content": ""},
+ ]
+ },
+ }
+ )
+ llm_response = ModelResponse(
+ choices=[
+ {
+ "finish_reason": "stop",
+ "index": 0,
+ "message": {"content": "secret PII", "role": "assistant"},
+ }
+ ]
+ )
+ with patch(
+ "litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.post",
+ return_value=anonymize_response,
+ ):
+ result = await guard.async_post_call_success_hook(
+ data=request_data,
+ response=llm_response,
+ user_api_key_dict=UserAPIKeyAuth(),
+ )
+ assert isinstance(result, ModelResponse)
+ assert result.choices[0].message.content == ""
+
+
@pytest.mark.asyncio
async def test_post_call_success_hook_no_action_keeps_content():
guard = _make_guardrail()