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 configured

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Treat this as intended control flow: the guardrail flagged the response — fix the prompt/data or tune the guardrail rules/thresholds
  2. If you own the guardrail, prefer configuring on_flagged_action ('blocked'/'masked') so the framework handles the response instead of the raw exception escaping
  3. 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

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


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