BerriAI/litellm · error · GuardrailRaisedException
Ovalix guardrail error: {e}
Error message
Ovalix guardrail error: {e} What it means
Runtime GuardrailRaisedException (litellm's canonical guardrail failure exception) from OvalixGuard._generate_post_guardrail_llm_texts: a checkpoint call made while post-processing LLM responses raised an unexpected Exception (network error, non-2xx, malformed JSON, timeout), which is wrapped with should_wrap_with_default_message=False so the underlying cause text is preserved in the message. Unlike the config errors, this is an Ovalix Tracker outage/communication problem mid-request.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/ovalix/ovalix.py:251
post_guardrail_texts: Final = await self._generate_post_guardrail_llm_texts(
texts, tracker_actor_id, session_id, self._pre_checkpoint_id
)
return {**inputs, "texts": post_guardrail_texts}
return inputs
async def _generate_post_guardrail_llm_texts(
self, texts: list[str], actor: str, session_id: str, checkpoint_id: str
) -> list[str]:
"""Generate post-guardrail LLM responses for the given LLM responses."""
post_guardrail_texts: Final[list[str]] = []
is_first_response = True
for llm_response in reversed(texts):
try:
resp = await self._call_checkpoint(llm_response, checkpoint_id, actor, session_id)
except Exception as e:
verbose_proxy_logger.exception("Ovalix apply_guardrail checkpoint call failed: %s", e)
raise GuardrailRaisedException(
guardrail_name=self.guardrail_name,
message=f"Ovalix guardrail error: {e}",
should_wrap_with_default_message=False,
) from e
action_type = (resp.get("action_type") or "").lower()
blocking_message = self._get_trackers_corrected_message(resp) or BLOCKED_BY_OVALIX_FALLBACK_MESSAGE
if action_type == BLOCKED_ACTION_TYPE and is_first_response:
self._block_current_message(blocking_message)
elif action_type == BLOCKED_ACTION_TYPE:
post_guardrail_texts.insert(0, blocking_message)
else:
corrected_text = self._get_trackers_corrected_message(resp) or llm_response
post_guardrail_texts.insert(0, corrected_text)
is_first_response = False
return post_guardrail_texts
def _block_current_message(self, blocking_message: str) -> None:View on GitHub (pinned to 77b7c6c40c)
Solutions
- Inspect the wrapped '{e}' text and the logged exception ('Ovalix apply_guardrail checkpoint call failed') to classify: connectivity vs auth vs payload
- Fix tracker reachability/credentials (tracker_api_base, tracker headers) and verify the application/checkpoint ids in the Ovalix console
- Retry the request once transient network blips are ruled in or out
- If tracker availability is spotty, decouple: run Ovalix in monitoring capacity or add circuit-breaking around guarded routes
Example fix
# before: single checkpoint call can abort the whole response
resp = await guard._call_checkpoint(text, checkpoint_id, actor, session_id)
# after: fail visibly but isolate per-call failures
try:
resp = await guard._call_checkpoint(text, checkpoint_id, actor, session_id)
except Exception as e:
log.error("ovalix checkpoint failed for session=%s: %s", session_id, e)
raise GuardrailRaisedException(
guardrail_name=guard.guardrail_name,
message=f"Ovalix guardrail error: {e}",
should_wrap_with_default_message=False,
) from e Defensive patterns
Strategy: try-catch
Validate before calling
# Operator preflight: probe the Ovalix tracker before enabling the guardrail in blocking mode
import httpx
def ovalix_tracker_reachable(api_base: str, headers: dict) -> bool:
try:
httpx.get(api_base, headers=headers, timeout=5.0)
return True
except (httpx.ConnectError, httpx.ReadTimeout):
return False Try / catch
from litellm.exceptions import GuardrailRaisedException
try:
result = await guard.apply_guardrail(inputs=texts, request_data=data, input_type="response")
except GuardrailRaisedException as e:
if str(e).startswith("Ovalix guardrail error:"):
# underlying cause preserved because should_wrap_with_default_message=False
log.exception("ovalix tracker failure", exc_info=e.__cause__)
if is_transient(e.__cause__): # timeout / 5xx
return await retry_once(guard, texts, data)
raise Prevention
- Set explicit timeouts on the Ovalix async handler so a slow tracker fails fast instead of hanging completions
- Monitor tracker availability and page on elevated GuardrailRaisedException rates from the Ovalix guard
- Keep a documented decision (and test) for whether Ovalix outages should block responses (fail closed) or pass through
When it happens
Trigger: Ovalix Tracker API base unreachable or timing out while post-call scanning responses; tracker returns 4xx/5xx (bad application_id/checkpoint pair, expired token); response body not valid JSON so parsing throws — any of these inside post-call handling of one or more LLM response texts
Common situations: Ovalix SaaS degradation or maintenance windows; on-prem tracker behind a flaky ingress; token used in tracker headers expiring mid-session; the reversed-order loop failing on the first response and aborting the whole completion
Related errors
- Cisco AI Defense {surface} API call timed out after {self.ti
- Cisco AI Defense {surface} API request failed: {exc}
- Lasso API timeout
- Failed to verify request safety with Lasso API: {error}
- Microsoft Purview DLP: upstream policy evaluation failed
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/68258ce46fa3a502.
Report an issue: GitHub.