BerriAI/litellm · error · HTTPException

Violated OpenAI moderation policy

Error message

Violated OpenAI moderation policy

What it means

Intentional content block from OpenAIModerationGuardrail._check_moderation_result: the moderation model flagged the text in one or more categories, and the guardrail (running in blocking mode) rejects the request/response with HTTP 400. The detail includes which categories fired and the full category_scores for auditability.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/openai/moderations.py:161

        if result.flagged:
            # Build detailed violation information
            violated_categories: Final = []
            if result.categories:
                for category, is_violated in result.categories.items():
                    if is_violated:
                        violated_categories.append(category)

            violation_details: Final = {
                "violated_categories": violated_categories,
                "category_scores": result.category_scores or {},
            }

            verbose_proxy_logger.warning(
                "OpenAI Moderation: Content flagged for violations: %s",
                violation_details,
            )

            raise HTTPException(
                status_code=400,
                detail={
                    "error": "Violated OpenAI moderation policy",
                    "moderation_result": violation_details,
                },
            )

    @log_guardrail_information
    async def apply_guardrail(
        self,
        inputs: GenericGuardrailAPIInputs,
        request_data: dict,
        input_type: Literal["request", "response"],
        logging_obj: Optional["LiteLLMLoggingObj"] = None,
    ) -> GenericGuardrailAPIInputs:
        """
        Apply OpenAI moderation guardrail using the unified guardrail interface.

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Catch the 400 client-side and degrade gracefully using violated_categories to tailor the message
  2. For legitimate content being over-flagged, pre-filter or rephrase at the application layer, or run the guardrail in log-only mode for those routes
  3. Review category_scores — near-threshold scores indicate borderline content you may choose to allow by switching to custom threshold handling
  4. Keep human-review flows for false positives rather than bypassing moderation entirely

Example fix

# before: error propagates raw
try:
    r = client.chat.completions.create(**params)
except Exception:
    abort(500)

# after: handle the moderation block specifically
from openai import BadRequestError
try:
    r = client.chat.completions.create(**params)
except BadRequestError as e:
    body = e.response.json()
    if body.get("error") == "Violated OpenAI moderation policy":
        cats = body["moderation_result"]["violated_categories"]
        return f"Content blocked ({', '.join(cats)}). Please rephrase.", 400
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

null  # moderation verdict is server-side; clients cannot pre-classify without reimplementing the model

Try / catch

from openai import BadRequestError

try:
    r = client.chat.completions.create(**params)
except BadRequestError as e:
    body = e.response.json()
    if body.get("error") == "Violated OpenAI moderation policy":
        cats = body["moderation_result"]["violated_categories"]
        return respond_block_page(cats)
    raise

Prevention

When it happens

Trigger: Pre-call moderation of prompts containing violence/self-harm/hate/sexual content matched by omni-moderation-latest; post-call streaming hook flagging a generated chunk; borderline content newly caught after OpenAI updates moderation models or thresholds

Common situations: User-generated content apps surfacing the raw 400 to end users; test fixtures containing edgy text that trips categories; legitimate content (medical, security research) being over-flagged by category thresholds

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/596e5248157b573b. Report an issue: GitHub.