{"record":{"id":"2346ae952b4ee0f8","repo":"BerriAI/litellm","slug":"request-blocked-by-onyx-guard-violations-detect","errorCode":null,"errorMessage":"Request blocked by Onyx Guard. Violations: {detection_message}.","messagePattern":"Request blocked by Onyx Guard\\. Violations: (.+?)\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/onyx/onyx.py","lineNumber":91,"sourceCode":"        response: Final = await self.async_handler.post(\n            f\"{self.api_base}/guard/evaluate/v1/{self.api_key}/litellm\",\n            json={\n                \"payload\": payload,\n                \"input_type\": input_type,\n                \"conversation_id\": conversation_id,\n            },\n            headers={\n                \"Content-Type\": \"application/json\",\n            },\n        )\n        response.raise_for_status()\n        result: Final = response.json()\n        if not result.get(\"allowed\", True):\n            detection_message = \"Unknown violation\"\n            if \"violated_rules\" in result:\n                detection_message = \", \".join(result[\"violated_rules\"])\n            verbose_proxy_logger.warning(\"Request blocked by Onyx Guard. Violations: %s.\", detection_message)\n            raise HTTPException(\n                status_code=400,\n                detail=f\"Request blocked by Onyx Guard. Violations: {detection_message}.\",\n            )\n        return result\n\n    @log_guardrail_information\n    async def apply_guardrail(\n        self,\n        inputs: GenericGuardrailAPIInputs,\n        request_data: dict,\n        input_type: Literal[\"request\", \"response\"],\n        logging_obj: Optional[\"LiteLLMLoggingObj\"] = None,\n    ) -> GenericGuardrailAPIInputs:\n        conversation_id: Final = logging_obj.litellm_call_id if logging_obj else str(uuid.uuid4())\n\n        verbose_proxy_logger.info(\n            \"Running Onyx Guard apply_guardrail hook\",\n            extra={\"conversation_id\": conversation_id, \"input_type\": input_type},","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/onyx/onyx.py#L73-L109","documentation":"Intentional block raised by OnyxGuard._validate_with_guard_server: the Onyx Guard server evaluated the payload and returned allowed=false, so the guardrail rejects the request with HTTP 400 and a detail listing the violated rules (joined from response['violated_rules'], or 'Unknown violation' if the server did not say). This is Onyx Guard policy doing its job, not an infrastructure fault.","triggerScenarios":"Prompt or response content matching an Onyx Guard rule (jailbreak patterns, sensitive topics, banned content) routed through a model with the onyx guardrail attached; tightening rules server-side so previously-passing traffic starts failing","commonSituations":"Red-team testing of guardrail coverage; policy updates by the security team; test suites asserting blocked prompts now seeing the block shape change","solutions":["Parse the 'Violations:' list from the 400 detail to identify which Onyx rules fired","Adjust the content, or have the Onyx admin tune the specific rule/threshold","On the client, catch the 400 and translate it into a user-facing policy message instead of crashing","If a rule is wrongly firing, capture the conversation_id sent to Onyx and review the evaluation there"],"exampleFix":"# before: generic crash on 400\nresp = httpx.post(f\"{PROXY}/chat/completions\", json=payload)\nresp.raise_for_status()\n\n# after: recognize the Onyx block\nresp = httpx.post(f\"{PROXY}/chat/completions\", json=payload)\nif resp.status_code == 400:\n    detail = resp.json()[\"detail\"]\n    if \"Onyx Guard\" in str(detail):\n        return {\"blocked\": True, \"violations\": detail}\nresp.raise_for_status()","handlingStrategy":"try-catch","validationCode":"null  # blocking decision happens server-side at Onyx; pre-validation would duplicate their rules","typeGuard":null,"tryCatchPattern":"try:\n    resp = httpx.post(f\"{PROXY}/chat/completions\", json=payload, timeout=30)\n    resp.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 400:\n        detail = e.response.json()[\"detail\"]\n        if \"Onyx Guard\" in detail:\n            return {\"blocked\": True, \"violations\": detail.split(\"Violations: \")[-1]}\n    raise","preventionTips":["Parse and log the violated-rules list to feed analytics on policy hits","Wrap guarded calls in an app-level helper that converts blocks into safe user messaging","Coordinate rule changes with the Onyx admin so client UX keeps pace with new blocks"],"tags":["onyx","guardrails","content-filter","policy-block","http-400"],"backgroundTag":"content-blocked-by-policy","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}