BerriAI/litellm · error · HTTPException

Request blocked by Onyx Guard. Violations: {detection_messag

Error message

Request blocked by Onyx Guard. Violations: {detection_message}.

What it means

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.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/onyx/onyx.py:91

        response: Final = await self.async_handler.post(
            f"{self.api_base}/guard/evaluate/v1/{self.api_key}/litellm",
            json={
                "payload": payload,
                "input_type": input_type,
                "conversation_id": conversation_id,
            },
            headers={
                "Content-Type": "application/json",
            },
        )
        response.raise_for_status()
        result: Final = response.json()
        if not result.get("allowed", True):
            detection_message = "Unknown violation"
            if "violated_rules" in result:
                detection_message = ", ".join(result["violated_rules"])
            verbose_proxy_logger.warning("Request blocked by Onyx Guard. Violations: %s.", detection_message)
            raise HTTPException(
                status_code=400,
                detail=f"Request blocked by Onyx Guard. Violations: {detection_message}.",
            )
        return result

    @log_guardrail_information
    async def apply_guardrail(
        self,
        inputs: GenericGuardrailAPIInputs,
        request_data: dict,
        input_type: Literal["request", "response"],
        logging_obj: Optional["LiteLLMLoggingObj"] = None,
    ) -> GenericGuardrailAPIInputs:
        conversation_id: Final = logging_obj.litellm_call_id if logging_obj else str(uuid.uuid4())

        verbose_proxy_logger.info(
            "Running Onyx Guard apply_guardrail hook",
            extra={"conversation_id": conversation_id, "input_type": input_type},

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Parse the 'Violations:' list from the 400 detail to identify which Onyx rules fired
  2. Adjust the content, or have the Onyx admin tune the specific rule/threshold
  3. On the client, catch the 400 and translate it into a user-facing policy message instead of crashing
  4. If a rule is wrongly firing, capture the conversation_id sent to Onyx and review the evaluation there

Example fix

# before: generic crash on 400
resp = httpx.post(f"{PROXY}/chat/completions", json=payload)
resp.raise_for_status()

# after: recognize the Onyx block
resp = httpx.post(f"{PROXY}/chat/completions", json=payload)
if resp.status_code == 400:
    detail = resp.json()["detail"]
    if "Onyx Guard" in str(detail):
        return {"blocked": True, "violations": detail}
resp.raise_for_status()
Defensive patterns

Strategy: try-catch

Validate before calling

null  # blocking decision happens server-side at Onyx; pre-validation would duplicate their rules

Try / catch

try:
    resp = httpx.post(f"{PROXY}/chat/completions", json=payload, timeout=30)
    resp.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code == 400:
        detail = e.response.json()["detail"]
        if "Onyx Guard" in detail:
            return {"blocked": True, "violations": detail.split("Violations: ")[-1]}
    raise

Prevention

When it happens

Trigger: 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

Common situations: Red-team testing of guardrail coverage; policy updates by the security team; test suites asserting blocked prompts now seeing the block shape change

Related errors


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