BerriAI/litellm · error · GraySwanGuardrailAPIError
{exc}
Error message
{exc} What it means
GraySwanGuardrailAPIError raised at the top of GraySwanGuardrail.apply_guardrail's exception handler when fail_open is False (it defaults to True) and the caught exception is not a guardrail decision (block/passthrough exceptions propagate via _is_grayswan_exception). It re-raises existing GraySwanGuardrailAPIError as-is, or wraps any other exception with its string form and a best-effort status_code. The guardrail failure is logged first via _log_guardrail_failure.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/grayswan/grayswan.py:253
raise
end_time: Final = time.time()
status_code: Final = getattr(exc, "status_code", None) or getattr(exc, "exception_status_code", None)
self._log_guardrail_failure(
exc=exc,
request_data=request_data or {},
start_time=start_time,
end_time=end_time,
status_code=status_code,
)
if self.fail_open:
verbose_proxy_logger.warning(
"Gray Swan Guardrail: fail_open=True. Allowing request to proceed despite error: %s",
exc,
)
return inputs
if isinstance(exc, GraySwanGuardrailAPIError):
raise exc
raise GraySwanGuardrailAPIError(str(exc), status_code=status_code) from exc
def _is_grayswan_exception(self, exc: Exception) -> bool:
# Guardrail decision (passthrough) should always propagate,
# regardless of fail_open.
if isinstance(exc, ModifyResponseException):
return True
detail: Final = getattr(exc, "detail", None)
if isinstance(detail, dict):
return detail.get("error") == GRAYSWAN_BLOCK_ERROR_MSG
return False
# ------------------------------------------------------------------
# Legacy Test Interface (for backward compatibility)
# ------------------------------------------------------------------
async def run_grayswan_guardrail(self, payload: dict) -> dict[str, Any]:
"""
Run the GraySwan guardrail on a payload.View on GitHub (pinned to 77b7c6c40c)
Solutions
- Check the logged guardrail failure entry for the wrapped cause and status code.
- Verify GRAYSWAN_API_KEY / GRAYSWAN_API_BASE and curl the monitor endpoint directly.
- Raise guardrail_timeout if slow responses are the cause, or lower it to fail faster.
- If availability matters more than strictness for this deployment, keep/set fail_open: true (default) so errors pass traffic through.
- Remember block/passthrough decisions always propagate regardless of fail_open — only infrastructure errors are affected.
Example fix
# before litellm_params: guardrail: grayswan fail_open: false guardrail_timeout: 30 # after litellm_params: guardrail: grayswan fail_open: false guardrail_timeout: 60
Defensive patterns
Strategy: fallback
Validate before calling
import os
missing = [v for v in ('GRAYSWAN_API_KEY',) if not os.getenv(v)]
if missing:
raise SystemExit(f'deploy blocked, missing env: {missing}') Type guard
from litellm.proxy.guardrails.guardrail_hooks.grayswan.grayswan import GraySwanGuardrailAPIError
def is_grayswan_api_error(exc: BaseException) -> bool:
return isinstance(exc, GraySwanGuardrailAPIError) Try / catch
from litellm.proxy.guardrails.guardrail_hooks.grayswan.grayswan import GraySwanGuardrailAPIError
try:
result = await guardrail.apply_guardrail(inputs, request_data, input_type, logging_obj)
except GraySwanGuardrailAPIError as e:
logger.warning('GraySwan API error, failing open: %s (status=%s)', e, getattr(e, 'status_code', None))
result = dict(inputs) Prevention
- Default fail_open=true already absorbs these errors; only set false when compliance requires it.
- Size guardrail_timeout to your GraySwan latency (p99) to avoid timeout-induced failures.
- Watch _log_guardrail_failure entries to distinguish auth vs capacity vs network faults.
When it happens
Trigger: fail_open explicitly set to false, and the monitor call fails — network error, timeout beyond guardrail_timeout (default 30s), non-2xx from raise_for_status, JSON decode failure; or any unexpected exception in response processing.
Common situations: Operators setting fail_open: false for strict compliance, then a GraySwan outage or timeout makes every request fail; oversized payloads timing out at the 30s default; auth failures after key rotation.
Related errors
- DeepKeep guardrail API failed: {error}
- Generic Guardrail API failed: {error}
- Gray Swan guardrail requires a guardrail_name
- Gray Swan API key missing. Set `GRAYSWAN_API_KEY` or pass `a
- Blocked by Gray Swan Guardrail
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/6213677ee8c2c017.
Report an issue: GitHub.