BerriAI/litellm · error · ValueError

Guardrail failed: {n} violation(s) detected

Error message

Guardrail failed: {n} violation(s) detected

What it means

ValueError raised in DynamoAIGuardrail.async_pre_call_hook when the DynamoAI moderation response reports at least one policy violation for the incoming request messages. The message is built by _create_error_message and enumerates the violated policy names, so 'N violation(s)' reflects how many configured policies matched. LiteLLM converts this into an HTTP 400 for the caller.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/dynamoai/dynamoai.py:328

        _messages: Final = data.get("messages")
        if _messages:
            result: Final = await self._call_dynamoai_guardrails(
                messages=_messages,
                text_type="input",
                request_data=data,
                event_type=GuardrailEventHooks.pre_call,
            )

            verbose_proxy_logger.debug("Guardrails async_pre_call_hook result=%s", result)

            # Process the guardrails response
            processed_result: Final = self._process_dynamoai_guardrails_response(result)
            violations_detected: Final = processed_result["violations_detected"]

            # If any violations are detected, raise an error
            if violations_detected:
                error_message: Final = self._create_error_message(processed_result)
                raise ValueError(error_message)

        # Add guardrail to applied guardrails header
        add_guardrail_to_applied_guardrails_header(request_data=data, guardrail_name=self.guardrail_name)

        return data

    async def async_moderation_hook(
        self,
        data: dict,
        user_api_key_dict: UserAPIKeyAuth,
        call_type: CallTypesLiteral,
    ):
        """
        Runs in parallel to LLM API call
        Runs on only Input

        This can NOT modify the input, only used to reject or accept a call before going to LLM API
        """

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the full error message — it lists each violated policy name after the count line.
  2. Remove or replace the triggering policy in DYNAMOAI_POLICY_IDS / policy_ids for this guardrail.
  3. Loosen the policy thresholds in the DynamoAI dashboard so legitimate content no longer matches.
  4. Narrow the guardrail scope: set mode to only the hooks you need (e.g. drop pre_call) or detach guardrail_name from models that must not be input-scanned.

Example fix

# before
litellm_params:
  guardrail: dynamoai
  mode: pre_call
  policy_ids: ['pii-strict', 'jailbreak', 'toxicity']

# after
litellm_params:
  guardrail: dynamoai
  mode: pre_call
  policy_ids: ['pii-strict']
Defensive patterns

Strategy: try-catch

Type guard

def is_dynamoai_violation(exc: BaseException) -> bool:
    return isinstance(exc, ValueError) and str(exc).startswith('Guardrail failed:') and 'violation(s) detected' in str(exc)

Try / catch

from litellm.exceptions import BadRequestError
try:
    resp = client.chat.completions.create(model=model, messages=msgs)
except BadRequestError as e:
    if 'violation(s) detected' in str(e):
        return moderation_rejection(str(e))  # 4xx payload with policy names
    raise

Prevention

When it happens

Trigger: A chat completion routed through a model with the dynamoai guardrail attached where mode includes pre_call, and the POST to /v1/moderation/analyze/ returns violations for any DYNAMOAI_POLICY_IDS policy on the input messages.

Common situations: Users sending content that trips a configured DynamoAI policy (PII, jailbreak, toxicity); policy_ids pointing at overly strict policies copied from another environment; testing with adversarial prompts while pre_call scanning is enabled.

Related errors


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