diff --git a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py index d6d2e014948..d6065ef73f5 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py +++ b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py @@ -1202,7 +1202,7 @@ class ContentFilterGuardrail(CustomGuardrail): ) verbose_proxy_logger.warning(error_msg) raise HTTPException( - status_code=403, + status_code=400, detail={ "error": error_msg, "category": category_name, @@ -1242,7 +1242,7 @@ class ContentFilterGuardrail(CustomGuardrail): ) verbose_proxy_logger.warning(error_msg) raise HTTPException( - status_code=403, + status_code=400, detail={ "error": error_msg, "category": category_name, @@ -1285,7 +1285,7 @@ class ContentFilterGuardrail(CustomGuardrail): error_msg = f"Content blocked: {pattern_name} pattern detected" verbose_proxy_logger.warning(error_msg) raise HTTPException( - status_code=403, + status_code=400, detail={"error": error_msg, "pattern": pattern_name}, ) elif action == ContentFilterAction.MASK: @@ -1325,7 +1325,7 @@ class ContentFilterGuardrail(CustomGuardrail): error_msg += f" ({description})" verbose_proxy_logger.warning(error_msg) raise HTTPException( - status_code=403, + status_code=400, detail={ "error": error_msg, "keyword": keyword, @@ -1677,7 +1677,7 @@ class ContentFilterGuardrail(CustomGuardrail): "ContentFilterGuardrail: competitor intent refuse - %s", intent_val ) raise HTTPException( - status_code=403, + status_code=400, detail={ "error": msg, "intent": intent_val, diff --git a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/test_eval.py b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/test_eval.py index 56398739b9b..aedc6acc810 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/test_eval.py +++ b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/test_eval.py @@ -59,7 +59,7 @@ def _run(checker, text: str) -> dict: checker.check(text) return {"decision": "ALLOW", "score": 0.0, "matched_topic": None} except HTTPException as e: - if e.status_code == 403: + if e.status_code == 400: detail: Dict[str, Any] = e.detail if isinstance(e.detail, dict) else {} return { "decision": "BLOCK", @@ -542,7 +542,7 @@ class _LlmJudgeChecker: if "BLOCK" in decision: raise HTTPException( - status_code=403, + status_code=400, detail={ "error": "Content blocked by LLM judge", "topic": "financial_advice", diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_competitor_intent.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_competitor_intent.py index 545b75fa06b..723d4b7db75 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_competitor_intent.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_competitor_intent.py @@ -226,7 +226,7 @@ class TestContentFilterWithCompetitorIntent: await guardrail.apply_guardrail( inputs, request_data={}, input_type="request" ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Exact config from litellm/proxy/_new_secret_config.yaml (lines 27-53). diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py index fb952d4b18b..bb079ea6580 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py @@ -198,7 +198,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "us_ssn" in str(exc_info.value.detail) @pytest.mark.asyncio @@ -563,7 +563,7 @@ class TestContentFilterGuardrail: ): pass - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "us_ssn" in str(exc_info.value.detail) @pytest.mark.asyncio @@ -1010,7 +1010,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "danger_word" in str(exc_info.value.detail) @pytest.mark.asyncio @@ -1298,7 +1298,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 detail = exc_info.value.detail if isinstance(detail, dict): assert detail.get("category") == "harm_toxic_abuse" @@ -1327,7 +1327,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 detail = exc_info.value.detail if isinstance(detail, dict): assert detail.get("category") == "harm_toxic_abuse" @@ -1375,7 +1375,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403, f"Failed to block: '{test_input}'" + assert exc_info.value.status_code == 400, f"Failed to block: '{test_input}'" detail = exc_info.value.detail if isinstance(detail, dict): assert detail.get("category") == "harm_toxic_abuse" @@ -1443,7 +1443,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "te*st" in str(exc_info.value.detail) def test_check_category_keywords_asterisk_pattern_matching(self): @@ -1510,7 +1510,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403, f"Failed to block: '{test_input}'" + assert exc_info.value.status_code == 400, f"Failed to block: '{test_input}'" detail = exc_info.value.detail if isinstance(detail, dict): assert detail.get("category") == "harm_toxic_abuse" @@ -1560,7 +1560,7 @@ class TestContentFilterGuardrail: input_type="request", ) - assert exc_info.value.status_code == 403, f"Failed to block: '{test_input}'" + assert exc_info.value.status_code == 400, f"Failed to block: '{test_input}'" detail = exc_info.value.detail if isinstance(detail, dict): assert detail.get("category") == "harm_toxic_abuse" @@ -1646,7 +1646,7 @@ class TestContentFilterGuardrail: ) assert ( - exc_info.value.status_code == 403 + exc_info.value.status_code == 400 ), f"Failed to block Spanish: '{test_input}'" @pytest.mark.asyncio @@ -1683,7 +1683,7 @@ class TestContentFilterGuardrail: ) assert ( - exc_info.value.status_code == 403 + exc_info.value.status_code == 400 ), f"Failed to block French: '{test_input}'" @pytest.mark.asyncio @@ -1720,7 +1720,7 @@ class TestContentFilterGuardrail: ) assert ( - exc_info.value.status_code == 403 + exc_info.value.status_code == 400 ), f"Failed to block German: '{test_input}'" @pytest.mark.asyncio @@ -1766,7 +1766,7 @@ class TestContentFilterGuardrail: ) assert ( - exc_info.value.status_code == 403 + exc_info.value.status_code == 400 ), f"Failed to block Australian: '{test_input}'" async def test_html_tags_in_messages_not_blocked(self): @@ -1942,7 +1942,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "harmful_child_safety" in str(exc_info.value.detail) # Test case 2: Should BLOCK - identifier + block word combination @@ -1956,7 +1956,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 3: Should BLOCK - explicit content + minors with pytest.raises(HTTPException) as exc_info: @@ -1967,7 +1967,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 4: Should NOT block - identifier word alone (no block word) result = await guardrail.apply_guardrail( @@ -2009,7 +2009,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 @pytest.mark.asyncio async def test_conditional_category_sentence_boundaries(self): @@ -2093,7 +2093,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 assert "bias_racial" in str(exc_info.value.detail) # Test case 2: Should BLOCK - identifier + dehumanizing language @@ -2107,7 +2107,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 3: Should BLOCK - supremacist content with pytest.raises(HTTPException) as exc_info: @@ -2120,7 +2120,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 4: Should BLOCK - elimination rhetoric with pytest.raises(HTTPException) as exc_info: @@ -2133,7 +2133,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 5: Should NOT block - identifier word alone (no block word) result = await guardrail.apply_guardrail( @@ -2171,7 +2171,7 @@ class TestContentFilterGuardrail: request_data={}, input_type="request", ) - assert exc_info.value.status_code == 403 + assert exc_info.value.status_code == 400 # Test case 9: Should NOT block - block word alone (no identifier) result = await guardrail.apply_guardrail(