{"record":{"id":"68258ce46fa3a502","repo":"BerriAI/litellm","slug":"ovalix-guardrail-error-e","errorCode":null,"errorMessage":"Ovalix guardrail error: {e}","messagePattern":"Ovalix guardrail error: (.+?)","errorType":"exception","errorClass":"GuardrailRaisedException","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/ovalix/ovalix.py","lineNumber":251,"sourceCode":"            post_guardrail_texts: Final = await self._generate_post_guardrail_llm_texts(\n                texts, tracker_actor_id, session_id, self._pre_checkpoint_id\n            )\n            return {**inputs, \"texts\": post_guardrail_texts}\n        return inputs\n\n    async def _generate_post_guardrail_llm_texts(\n        self, texts: list[str], actor: str, session_id: str, checkpoint_id: str\n    ) -> list[str]:\n        \"\"\"Generate post-guardrail LLM responses for the given LLM responses.\"\"\"\n        post_guardrail_texts: Final[list[str]] = []\n\n        is_first_response = True\n        for llm_response in reversed(texts):\n            try:\n                resp = await self._call_checkpoint(llm_response, checkpoint_id, actor, session_id)\n            except Exception as e:\n                verbose_proxy_logger.exception(\"Ovalix apply_guardrail checkpoint call failed: %s\", e)\n                raise GuardrailRaisedException(\n                    guardrail_name=self.guardrail_name,\n                    message=f\"Ovalix guardrail error: {e}\",\n                    should_wrap_with_default_message=False,\n                ) from e\n\n            action_type = (resp.get(\"action_type\") or \"\").lower()\n            blocking_message = self._get_trackers_corrected_message(resp) or BLOCKED_BY_OVALIX_FALLBACK_MESSAGE\n            if action_type == BLOCKED_ACTION_TYPE and is_first_response:\n                self._block_current_message(blocking_message)\n            elif action_type == BLOCKED_ACTION_TYPE:\n                post_guardrail_texts.insert(0, blocking_message)\n            else:\n                corrected_text = self._get_trackers_corrected_message(resp) or llm_response\n                post_guardrail_texts.insert(0, corrected_text)\n            is_first_response = False\n        return post_guardrail_texts\n\n    def _block_current_message(self, blocking_message: str) -> None:","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/ovalix/ovalix.py#L233-L269","documentation":"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.","triggerScenarios":"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","commonSituations":"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","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"],"exampleFix":"# before: single checkpoint call can abort the whole response\nresp = await guard._call_checkpoint(text, checkpoint_id, actor, session_id)\n\n# after: fail visibly but isolate per-call failures\ntry:\n    resp = await guard._call_checkpoint(text, checkpoint_id, actor, session_id)\nexcept Exception as e:\n    log.error(\"ovalix checkpoint failed for session=%s: %s\", session_id, e)\n    raise GuardrailRaisedException(\n        guardrail_name=guard.guardrail_name,\n        message=f\"Ovalix guardrail error: {e}\",\n        should_wrap_with_default_message=False,\n    ) from e","handlingStrategy":"try-catch","validationCode":"# Operator preflight: probe the Ovalix tracker before enabling the guardrail in blocking mode\nimport httpx\n\ndef ovalix_tracker_reachable(api_base: str, headers: dict) -> bool:\n    try:\n        httpx.get(api_base, headers=headers, timeout=5.0)\n        return True\n    except (httpx.ConnectError, httpx.ReadTimeout):\n        return False","typeGuard":null,"tryCatchPattern":"from litellm.exceptions import GuardrailRaisedException\n\ntry:\n    result = await guard.apply_guardrail(inputs=texts, request_data=data, input_type=\"response\")\nexcept GuardrailRaisedException as e:\n    if str(e).startswith(\"Ovalix guardrail error:\"):\n        # underlying cause preserved because should_wrap_with_default_message=False\n        log.exception(\"ovalix tracker failure\", exc_info=e.__cause__)\n        if is_transient(e.__cause__):  # timeout / 5xx\n            return await retry_once(guard, texts, data)\n    raise","preventionTips":["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"],"tags":["ovalix","guardrails","upstream","network","wrapping"],"backgroundTag":"upstream-api-error","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}