BerriAI/litellm · error · ValueError

Cisco AI Defense guardrail: invalid rule definition: {rule!r

Error message

Cisco AI Defense guardrail: invalid rule definition: {rule!r}

What it means

ValueError raised while normalizing the Cisco AI Defense guardrail's rules config (_normalize_rules-style path): a rules entry was neither a plain string (shorthand for a rule name) nor a mapping the normalizer could extract a rule_name from. The offending value is echoed with {rule!r}, so the config mistake is directly visible. This is a config-shape validation error raised at guardrail init time.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/cisco_ai_defense/cisco_ai_defense.py:940

                    rule = dumped

        if isinstance(rule, dict):
            normalized: Final[dict[str, object]] = {}
            rule_name: Final = rule.get("rule_name")
            if rule_name:
                normalized["rule_name"] = rule_name
            entity_types: Final = rule.get("entity_types")
            if entity_types:
                normalized["entity_types"] = list(entity_types)
            rule_id: Final = rule.get("rule_id")
            if rule_id is not None:
                normalized["rule_id"] = rule_id
            classification: Final = rule.get("classification")
            if classification:
                normalized["classification"] = classification
            return normalized

        raise ValueError(f"Cisco AI Defense guardrail: invalid rule definition: {rule!r}")

    # ------------------------------------------------------------------
    # Response processing
    # ------------------------------------------------------------------

    def _finalize_inspection(
        self,
        inspect_response: dict[str, Any],
        request_data: dict,
        context: _ScanContext,
        start_time: datetime,
        response_obj: object = None,
    ) -> dict[str, object]:
        """Parse, log, and (optionally) raise/redact on the Cisco verdict.

        ``context.direction`` is ``"input"`` for request scans and ``"output"``
        for response scans (used for metadata namespacing and response headers).
        ``response_obj`` is the LiteLLM response object (or MCP tool-call

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Check the echoed {rule!r} in the error — it shows exactly which entry is invalid.
  2. Make each rules entry either a plain string ("rule-name") or a dict with recognized keys: rule_name (or shorthand), entity_types (list), rule_id, classification.
  3. Validate the config with a YAML/JSON schema check before deploying; reload the proxy after fixing.

Example fix

# before — entry has unrecognized keys only
litellm_params:
  guardrail: cisco_ai_defense
  rules:
    - rulename: prompt_injection

# after
litellm_params:
  guardrail: cisco_ai_defense
  rules:
    - rule_name: prompt_injection
      entity_types: [PROMPT_INJECTION]
Defensive patterns

Strategy: type-guard

Validate before calling

def normalize_rule(r):
    if isinstance(r, str) and r.strip():
        return {"rule_name": r}
    if isinstance(r, dict) and (r.get("rule_name") or any(k in r for k in ("entity_types", "rule_id", "classification"))):
        out = {k: v for k, v in r.items() if k in ("rule_name", "entity_types", "rule_id", "classification")}
        if "rule_name" not in out:
            out["rule_name"] = r.get("rule_name") or r.get("name")
        return out
    raise ValueError(f"invalid cisco rule definition: {r!r}")
rules = [normalize_rule(r) for r in config_rules]  # run before writing config

Type guard

from typing import Any
def is_valid_cisco_rule(rule: Any) -> bool:
    if isinstance(rule, str):
        return bool(rule.strip())
    return (isinstance(rule, dict)
            and isinstance(rule.get("rule_name"), str)
            and ("entity_types" not in rule or isinstance(rule["entity_types"], list)))

Prevention

When it happens

Trigger: Passing rules: [123, null, [], {"name": ...}] — i.e., entries that are not strings and not dicts carrying the recognized keys (rule_name via shorthand, entity_types, rule_id, classification). Also strings that aren't matched and dicts missing every recognized field fall through to this raise.

Common situations: Converting a rules config from another format (YAML anchors producing None, JSON numbers), typos like {"rulename": "x"} instead of rule_name, or copy-pasting Cisco console JSON where rule entries are nested one level deeper than expected.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


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