BerriAI/litellm · error · ModifyResponseException
{violation_message}
Error message
{violation_message} What it means
raise_modify_response_exception() is a helper on CustomGuardrail that subclasses call to reject a completed LLM response: it raises ModifyResponseException carrying the guardrail name, detection_info, request data, and the original response so the proxy can surface the rejection. The message is fully caller-supplied ({violation_message}), typically built by _format_violation_message to name what was detected.
Source
Thrown at litellm/integrations/custom_guardrail.py:240
the synthetic block response reports it instead of zeros. Leave None
for pre-call/during-call blocks (the LLM was never invoked).
Raises:
ModifyResponseException: Always raises this exception to short-circuit
the LLM call and return the violation message
Example:
if violation_detected and self.on_flagged_action == "passthrough":
message = self._format_violation_message(detection_info)
self.raise_passthrough_exception(
violation_message=message,
request_data=data,
detection_info=detection_info
)
"""
model: Final = request_data.get("model", "unknown")
raise ModifyResponseException(
message=violation_message,
model=model,
request_data=request_data,
guardrail_name=self.guardrail_name,
detection_info=detection_info,
original_response=original_response,
)
def raise_sensitive_data_route_exception(
self,
route_to_model: str,
request_data: dict[str, Any],
detection_info: dict[str, Any] | None = None,
) -> None:
"""
Raise an exception to reroute the request to a different model.
Use this when sensitive data is detected and the guardrail is configuredView on GitHub (pinned to 77b7c6c40c)
Solutions
- Treat this as intended control flow: the guardrail flagged the response — fix the prompt/data or tune the guardrail rules/thresholds
- If you own the guardrail, prefer configuring on_flagged_action ('blocked'/'masked') so the framework handles the response instead of the raw exception escaping
- Catch ModifyResponseException where you invoke litellm and map it to a 4xx with the detection metadata for clients
Example fix
# before
class MyGuardrail(CustomGuardrail):
async def async_moderation_hook(self, data, response):
if violation_detected:
raise HTTPException(400, 'blocked') # untyped, loses detection_info
# after
class MyGuardrail(CustomGuardrail):
async def async_moderation_hook(self, data, response):
if violation_detected:
self.raise_modify_response_exception(
violation_message=self._format_violation_message(detection_info),
request_data=data, detection_info=detection_info,
original_response=response)
# caller: except ModifyResponseException as e: return JSONResponse(status_code=400, content={'error': str(e)}) Defensive patterns
Strategy: try-catch
Try / catch
try:
resp = await litellm.acompletion(...)
except ModifyResponseException as e:
# guardrail flagged the completed response
return JSONResponse(status_code=400, content={'error': str(e), 'guardrail': e.guardrail_name}) Prevention
- Map guardrail rejections to typed 4xx responses at the client boundary instead of crashing
- Tune guardrail rules to reduce false positives before enforcing block behavior
- Log detection_info from the exception for audit trails
When it happens
Trigger: A custom guardrail's response hook detects a violation and calls raise_modify_response_exception(violation_message=..., request_data=..., detection_info=...) — the template in this entry is the parameter, not a literal; guardrail unit tests exercising the flagged path.
Common situations: Writing custom guardrails on top of CustomGuardrail; PII/secrets/PCI detectors flagging model output; migrating a guardrail from manual HTTPException raises to the typed helper.
Related errors
- Sensitive data detected by {self.guardrail_name} (routing sk
- Sensitive data detected by {self.guardrail_name}
- CodeInterpreterInterception: no sandbox available. Provide a
- Cannot route sensitive data without a session_id. Ensure the
- Event hook {hook} is not in the supported event hooks {suppo
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/dc5a3e64183e2a25.
Report an issue: GitHub.