BerriAI/litellm · error · HTTPException

Blocked by Gray Swan Guardrail

Error message

Blocked by Gray Swan Guardrail

What it means

fastapi HTTPException(400) raised from GraySwanGuardrail._process_grayswan_response when on_flagged_action is 'block' and the monitor response's violation score meets or exceeds violation_threshold. The detail payload carries structured diagnostics: violation_location (input vs output based on the hook), violation score, violated_rules, mutation, and ipi flags. The proxy surfaces it as an HTTP 400 whose body contains this detail dict.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py:344

            "flagged": True,
            "violation_score": violation_score,
            "violated_rules": violated_rules,
            "mutation": mutation_detected,
            "ipi": ipi_detected,
        }

        # Determine if this is input (pre-call/during-call) or output (post-call)
        if hook_type is not None:
            is_input = hook_type in [
                GuardrailEventHooks.pre_call,
                GuardrailEventHooks.during_call,
            ]
        else:
            is_input = True

        if self.on_flagged_action == "block":
            violation_location: Final = "output" if (not is_input) else "input"
            raise HTTPException(
                status_code=400,
                detail={
                    "error": GRAYSWAN_BLOCK_ERROR_MSG,
                    "violation_location": violation_location,
                    "violation": violation_score,
                    "violated_rules": violated_rules,
                    "mutation": mutation_detected,
                    "ipi": ipi_detected,
                },
            )
        elif self.on_flagged_action == "passthrough":
            # For passthrough mode, we need to handle violations
            detections: Final = [detection_info]
            violation_message: Final = self._format_violation_message(detections, is_output=not is_input)
            verbose_proxy_logger.info("Gray Swan Guardrail: Passthrough mode - handling violation")

            # If hook_type is provided and in pre/during call, raise exception
            if hook_type in [

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the detail dict from the 400 body — violated_rules and violation score tell you which rule fired and by how much.
  2. Raise violation_threshold in the guardrail config so borderline content passes.
  3. Switch on_flagged_action to 'passthrough' to annotate metadata instead of blocking while you tune.
  4. Retune the specific violated rules in the GraySwan policy (or via policy_id/categories).

Example fix

# before
litellm_params:
  guardrail: grayswan
  on_flagged_action: block
  violation_threshold: 0.1

# after
litellm_params:
  guardrail: grayswan
  on_flagged_action: block
  violation_threshold: 0.6
Defensive patterns

Strategy: try-catch

Type guard

from fastapi import HTTPException

def is_grayswan_block(exc: BaseException) -> bool:
    detail = getattr(exc, 'detail', None)
    return isinstance(exc, HTTPException) and isinstance(detail, dict) and detail.get('error') == 'Blocked by Gray Swan Guardrail'

Try / catch

from litellm.exceptions import BadRequestError
import json
try:
    resp = client.chat.completions.create(model=model, messages=msgs)
except BadRequestError as e:
    if 'Blocked by Gray Swan Guardrail' in str(e):
        # proxy 400 body carries detail: violation, violated_rules, mutation, ipi
        return {'blocked': True, 'raw': str(e)}
    raise

Prevention

When it happens

Trigger: pre_call/during_call hooks where user input scores >= violation_threshold; post_call hooks where model output exceeds it; prompt-injection or policy tests deliberately pushing scores over the line.

Common situations: violation_threshold set too low so borderline legitimate content is blocked; on_flagged_action left at 'block' when 'passthrough' (annotate but allow) was intended; users reporting 400s with 'Blocked by Gray Swan Guardrail' in the error body.

Related errors


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