{"record":{"id":"bd30a2d0fd3bed12","repo":"BerriAI/litellm","slug":"refusal","errorCode":null,"errorMessage":"{refusal}","messagePattern":"\\{refusal\\}","errorType":"exception","errorClass":"ModifyResponseException","httpStatus":null,"severity":"error","filePath":"litellm/integrations/rubrik.py","lineNumber":378,"sourceCode":"            # supplies the prompt as ``texts`` with no structured_messages.\n            # Synthesise a user-message so the webhook can evaluate the prompt.\n            texts: Final = inputs.get(\"texts\")\n            if texts:\n                joined: Final = \"\\n\".join(t for t in texts if t)\n                if joined:\n                    messages = [{\"role\": \"user\", \"content\": joined}]\n        if not messages:\n            return inputs\n\n        payload: Final = self._build_prompt_moderation_payload(inputs, request_data)\n        service_response: Final = await self._post_to_prompt_moderation_endpoint(payload)\n        refusal: Final = self._extract_prompt_refusal(service_response)\n        if refusal is None:\n            return inputs\n\n        model: Final = inputs.get(\"model\") or request_data.get(\"model\") or \"unknown\"\n        self._stash_block_context(logging_obj, request_data)\n        raise ModifyResponseException(\n            message=refusal,\n            model=model,\n            request_data=request_data,\n            guardrail_name=self.guardrail_name,\n        )\n\n    @staticmethod\n    def _stash_block_context(\n        logging_obj: Optional[\"LiteLLMLoggingObj\"],\n        request_data: dict,\n    ) -> None:\n        \"\"\"Stash signals so the deferred success-event skips this request and\n        ``async_post_call_failure_hook`` can build the failure payload.\n\n        - Sets a flag on ``logging_obj.model_call_details`` so the deferred\n          success-event handler short-circuits.\n        - Stashes a reference to ``logging_obj`` on ``request_data`` under a\n          custom key. ``ProxyLogging.post_call_failure_hook`` pops only","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/rubrik.py#L360-L396","documentation":"Before the LLM call, the Rubrik guardrail moderates the prompt: it builds a prompt payload from the incoming messages, POSTs it to the prompt-moderation webhook, and if the service returns a refusal, _extract_prompt_refusal's result is raised as ModifyResponseException(message=refusal, model, request_data, guardrail_name='rubrik'). The proxy turns it into an HTTP 400-style error with the refusal text; nothing is sent to the model.","triggerScenarios":"A user prompt (or joined message content) matching a Rubrik policy in pre_call/prompt-moderation mode: the webhook answers with a refusal and litellm blocks the request before dispatch.","commonSituations":"Sensitive-topic policies rejecting legitimate prompts (false positives); red-team testing hitting the guardrail on purpose; prompt-injection detection rules firing on crafted inputs.","solutions":["Read the refusal message in the exception/proxy 400 body to identify the triggering policy","Tune the Rubrik policy or allowlist terms if the prompt was legitimate","Handle the block client-side: catch ModifyResponseException (SDK) or consume the proxy's structured guardrail error","Use the stashed block context/logs to audit exactly which input text was flagged"],"exampleFix":"# before\nresp = litellm.completion(model='gpt-4o', messages=[{'role': 'user', 'content': user_q}])\n# ModifyResponseException: <refusal from rubrik>\n\n# after\nfrom litellm.exceptions import ModifyResponseException\ntry:\n    resp = litellm.completion(model='gpt-4o', messages=[{'role': 'user', 'content': user_q}])\nexcept ModifyResponseException as e:\n    return {'blocked': True, 'reason': e.message, 'guardrail': 'rubrik'}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"from litellm.exceptions import ModifyResponseException\n\ndef is_guardrail_block(exc: BaseException) -> bool:\n    return isinstance(exc, ModifyResponseException)","tryCatchPattern":"from litellm.exceptions import ModifyResponseException\n\ntry:\n    resp = litellm.completion(model=model, messages=messages)\nexcept ModifyResponseException as e:\n    return {'blocked': True, 'guardrail': 'rubrik', 'reason': e.message}","preventionTips":["Surface prompt-moderation refusals as user-facing 400 responses with the explanation, never as stack traces","Track block rates per policy to spot over-broad rules","Keep Rubrik policy tuning in the loop when legitimate prompts get rejected"],"tags":["rubrik","guardrail","content-moderation","prompt-blocking","modify-response-exception"],"backgroundTag":"guardrail-content-blocked","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}