BerriAI/litellm · error · OvalixGuardrailMissingSecrets

Missing Ovalix guardrail configuration errors: {errors}

Error message

Missing Ovalix guardrail configuration errors: {errors}

What it means

Init-time OvalixGuardrailMissingSecrets (custom Exception subclass) from OvalixGuardrail._validate_config. It aggregates every missing required setting into one message: OVALIX_APPLICATION_ID (always required), OVALIX_PRE_CHECKPOINT_ID (required only when the pre_call hook is enabled), OVALIX_POST_CHECKPOINT_ID (required only when post_call is enabled), plus a combined error when neither checkpoint id exists. Values come from env vars or constructor params.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/ovalix/ovalix.py:133

        errors: Final[list[str]] = []

        if not self._tracker_api_base:
            errors.append("Tracker API base, set OVALIX_TRACKER_API_BASE or pass tracker_api_base")
        if not self._tracker_api_key:
            errors.append("Tracker API key, set OVALIX_TRACKER_API_KEY or pass tracker_api_key")
        if not self._application_id:
            errors.append("Application ID, set OVALIX_APPLICATION_ID or pass application_id")
        if not self._pre_checkpoint_id and GuardrailEventHooks.pre_call in supported_event_hooks:
            errors.append("Pre-checkpoint ID, set OVALIX_PRE_CHECKPOINT_ID or pass pre_checkpoint_id")
        if not self._post_checkpoint_id and GuardrailEventHooks.post_call in supported_event_hooks:
            errors.append("Post-checkpoint ID, set OVALIX_POST_CHECKPOINT_ID or pass post_checkpoint_id")
        if not self._pre_checkpoint_id and not self._post_checkpoint_id:
            errors.append(
                "Pre-checkpoint ID or Post-checkpoint ID, set OVALIX_PRE_CHECKPOINT_ID or OVALIX_POST_CHECKPOINT_ID or pass pre_checkpoint_id or post_checkpoint_id"
            )

        if errors:
            raise OvalixGuardrailMissingSecrets("Missing Ovalix guardrail configuration errors: " + ". ".join(errors))

        # auto-add hooks when checkpoint IDs are present
        if self._pre_checkpoint_id and GuardrailEventHooks.pre_call not in supported_event_hooks:
            supported_event_hooks.append(GuardrailEventHooks.pre_call)
        if self._post_checkpoint_id and GuardrailEventHooks.post_call not in supported_event_hooks:
            supported_event_hooks.append(GuardrailEventHooks.post_call)

    def _get_actor(self, data: dict) -> str:
        """Return a stable actor identifier from request metadata (e.g. user email or id)."""
        metadata: Final = data.get("metadata") or data.get("litellm_metadata") or {}
        if metadata.get("user_api_key_user_email"):
            return metadata["user_api_key_user_email"]
        if metadata.get("user_api_key_user_id"):
            return metadata["user_api_key_user_id"]
        return "unknown"

    def _get_tracker_actor_id(self, data: dict) -> str:
        """Normalize the actor string into a short, stable id for Tracker API payloads."""

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the message — it lists exactly which pieces are missing and which env var or param supplies each
  2. Set OVALIX_APPLICATION_ID plus the checkpoint id(s) matching the hooks you enabled (or pass application_id/pre_checkpoint_id/post_checkpoint_id in litellm_params)
  3. If you only need one direction of checking, restrict supported hooks/mode so only the matching checkpoint id is required
  4. Restart the proxy after the secrets are present

Example fix

# before
environment:
  - OVALIX_APPLICATION_ID=app_123

# after
environment:
  - OVALIX_APPLICATION_ID=app_123
  - OVALIX_PRE_CHECKPOINT_ID=chk_pre_456
  - OVALIX_POST_CHECKPOINT_ID=chk_post_789
Defensive patterns

Strategy: validation

Validate before calling

import os

required_always = ["OVALIX_APPLICATION_ID"]
hooks = set(cfg_guardrail.get("supported_event_hooks", []))
need = list(required_always)
if "pre_call" in hooks or cfg_guardrail.get("mode") == "pre_call":
    need.append("OVALIX_PRE_CHECKPOINT_ID")
if "post_call" in hooks or cfg_guardrail.get("mode") == "post_call":
    need.append("OVALIX_POST_CHECKPOINT_ID")

missing = [v for v in need if not os.getenv(v)]
assert not missing, f"missing Ovalix env: {missing}"

Try / catch

try:
    from litellm.proxy.guardrails.guardrail_hooks.ovalix.ovalix import OvalixGuard
    guard = OvalixGuard(guardrail_name="ovalix", **lp)
except Exception as e:  # OvalixGuardrailMissingSecrets subclasses Exception
    if "Missing Ovalix guardrail configuration" in str(e):
        fail_deploy(str(e))  # message already itemizes what is missing
    raise

Prevention

When it happens

Trigger: Configuring guardrail: ovalix without any OVALIX_* env vars; enabling mode: pre_call but providing only the post checkpoint id; empty-string env values counting as missing; deploying the proxy in an environment where the Ovalix secrets were never injected

Common situations: K8s/compose deployments missing the Ovalix secret mounts; enabling an extra event hook (e.g. adding post_call for output scanning) without also adding OVALIX_POST_CHECKPOINT_ID; local dev with a partial .env

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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