{"record":{"id":"3178a51a95a917f1","repo":"BerriAI/litellm","slug":"content-violates-policy-3178a5","errorCode":null,"errorMessage":"Content violates policy","messagePattern":"Content violates policy","errorType":"exception","errorClass":"GuardrailRaisedException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/generic_guardrail_api/generic_guardrail_api.py","lineNumber":463,"sourceCode":"            response: Final = await self.async_handler.post(\n                url=self.api_base,\n                json=guardrail_request.model_dump(mode=\"json\"),\n                headers=headers,\n            )\n\n            response.raise_for_status()\n            response_json: Final = response.json()\n\n            verbose_proxy_logger.debug(\"Generic Guardrail API response: %s\", response_json)\n\n            guardrail_response: Final = GenericGuardrailAPIResponse.from_dict(response_json)\n\n            # Handle the response\n            if guardrail_response.action == \"BLOCKED\":\n                # Block the request\n                error_message: Final = guardrail_response.blocked_reason or \"Content violates policy\"\n                verbose_proxy_logger.warning(\"Generic Guardrail API blocked request: %s\", error_message)\n                raise GuardrailRaisedException(\n                    guardrail_name=GUARDRAIL_NAME,\n                    message=error_message,\n                    should_wrap_with_default_message=False,\n                )\n\n            return self._build_guardrail_return_inputs(\n                texts=texts,\n                images=images,\n                tools=tools,\n                guardrail_response=guardrail_response,\n            )\n\n        except GuardrailRaisedException:\n            raise\n        except Timeout as e:\n            return self._handle_guardrail_request_error(e, inputs, input_type, logging_obj)\n        except httpx.HTTPStatusError as e:\n            status_code: Final = getattr(getattr(e, \"response\", None), \"status_code\", None)","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/generic_guardrail_api/generic_guardrail_api.py#L445-L481","documentation":"GuardrailRaisedException raised when the generic guardrail service response parses to action == 'BLOCKED' (via GenericGuardrailAPIResponse.from_dict). The message is blocked_reason from the response, or the fallback 'Content violates policy' when the service blocks without a reason. should_wrap_with_default_message=False forwards the message verbatim; the proxy returns it as a 400 to the caller.","triggerScenarios":"Any configured hook (pre_call/during_call/post_call) where the generic guardrail service evaluates the texts/images/tools/tool_calls payload and responds with action BLOCKED.","commonSituations":"Custom moderation service flagging legitimate traffic after a policy update; a new deployment whose block rules are stricter than the legacy ones it replaced; users probing the guardrail to see what is rejected.","solutions":["Check the proxy warning 'Generic Guardrail API blocked request: <reason>' for the service-supplied reason.","Update the block rules/thresholds in your guardrail service so the flagged content passes.","Ensure the service always returns blocked_reason — the fallback message carries no diagnostics.","Scope the guardrail by mode or model attachment if only some traffic should be moderated."],"exampleFix":"# before: server response omits reason\n{\"action\": \"BLOCKED\"}\n\n# after: always include a reason\n{\"action\": \"BLOCKED\", \"blocked_reason\": \"PII detected: email address\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"from litellm.proxy.guardrails.guardrails import GuardrailRaisedException\n\ndef is_guardrail_block(exc: BaseException) -> bool:\n    return isinstance(exc, GuardrailRaisedException)","tryCatchPattern":"from litellm.exceptions import BadRequestError\ntry:\n    resp = client.chat.completions.create(model=model, messages=msgs)\nexcept BadRequestError as e:\n    if 'Content violates policy' in str(e):\n        return {'blocked': True, 'reason': str(e)}\n    raise","preventionTips":["Always populate blocked_reason in your guardrail service responses for diagnosable 400s.","Shadow-test new block rules in log-only mode before enforcing.","Track block rates per rule to catch over-broad rules."],"tags":["generic-guardrail","guardrail","content-moderation","blocked"],"backgroundTag":"guardrail-content-blocked","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}