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
- Read the full error message — it lists each violated policy name after the count line.
- Remove or replace the triggering policy in DYNAMOAI_POLICY_IDS / policy_ids for this guardrail.
- Loosen the policy thresholds in the DynamoAI dashboard so legitimate content no longer matches.
- 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
- Maintain a canary prompt set and run it against new policy_ids before rollout.
- Keep policy_ids pinned per environment instead of inheriting account-wide defaults.
- Log the full violation message server-side for policy tuning feedback loops.
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
- Guardrail failed: {n} violation(s) detected
- {blocked.explanation}
- {refusal}
- Violated CrowdStrike AIDR guardrail policy
- Content violates policy
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/6431049220e38d26.
Report an issue: GitHub.