{"record":{"id":"149adb494acba938","repo":"BerriAI/litellm","slug":"pattern-name-is-required-for-prebuilt-patterns","errorCode":null,"errorMessage":"pattern_name is required for prebuilt patterns","messagePattern":"pattern_name is required for prebuilt patterns","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py","lineNumber":738,"sourceCode":"\n        Returns:\n            True if severity meets or exceeds threshold\n        \"\"\"\n        severity_order: Final = {\"low\": 0, \"medium\": 1, \"high\": 2}\n        return severity_order.get(severity, 0) >= severity_order.get(threshold, 1)\n\n    def _add_pattern(self, pattern_config: ContentFilterPattern) -> None:\n        \"\"\"\n        Add a pattern to the compiled patterns list.\n\n        Args:\n            pattern_config: ContentFilterPattern configuration\n        \"\"\"\n        try:\n            extra_config: _PatternExtraLookup = {\"keyword_pattern\": None, \"allow_word_numbers\": False}\n            if pattern_config.pattern_type == \"prebuilt\":\n                if not pattern_config.pattern_name:\n                    raise ValueError(\"pattern_name is required for prebuilt patterns\")\n                compiled = get_compiled_pattern(pattern_config.pattern_name)\n                pattern_name = pattern_config.pattern_name\n                extra_config = self._lookup_pattern_extra(pattern_name)\n            elif pattern_config.pattern_type == \"regex\":\n                if not pattern_config.pattern:\n                    raise ValueError(\"pattern is required for regex patterns\")\n                compiled = re.compile(pattern_config.pattern, re.IGNORECASE)\n                pattern_name = pattern_config.name or \"custom_regex\"\n            else:\n                raise ValueError(f\"Unknown pattern_type: {pattern_config.pattern_type}\")\n\n            keyword_pattern: Final = extra_config[\"keyword_pattern\"]\n            keyword_regex: Final = re.compile(keyword_pattern, re.IGNORECASE) if keyword_pattern else None\n\n            self.compiled_patterns.append(\n                {\n                    \"regex\": compiled,\n                    \"pattern_name\": pattern_name,","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py#L720-L756","documentation":"ValueError raised in ContentFilterGuardrail._add_pattern when a patterns[] config entry declares pattern_type: \"prebuilt\" but omits pattern_name. Prebuilt patterns are looked up by name via get_compiled_pattern(), so without a name the guardrail cannot know which regex (SSN, credit card, email, ...) to compile.","triggerScenarios":"Config yaml contains litellm_params.patterns with an entry like {pattern_type: prebuilt, action: BLOCK} that lacks pattern_name, and the guardrail initialization loop calls _add_pattern on it.","commonSituations":"Copied example config with the placeholder name deleted; assumption that the generic `name` field selects the prebuilt pattern; refactoring that renamed/dropped the field.","solutions":["Add pattern_name to the entry with a value from the prebuilt catalog (check get_compiled_pattern / the prebuilt registry for exact names, e.g. 'ssn', 'credit_card').","If you want a custom regex instead, switch the entry to pattern_type: regex and supply pattern.","Lint patterns at deploy time: prebuilt entries must have a non-empty pattern_name.","Confirm the name is not just present but spelled exactly as in the prebuilt catalog to avoid the next failure (unknown pattern lookup)."],"exampleFix":"# before\npatterns:\n  - pattern_type: prebuilt\n    action: BLOCK\n\n# after\npatterns:\n  - pattern_type: prebuilt\n    pattern_name: ssn\n    action: BLOCK","handlingStrategy":"validation","validationCode":"# Lint pattern entries: prebuilt requires pattern_name from the catalog\nfrom litellm.proxy.guardrails.guardrail_hooks.litellm_content_filter.patterns import get_compiled_pattern  # adjust import to repo\n\ndef lint_patterns(patterns: list[dict]) -> list[str]:\n    problems = []\n    for p in patterns:\n        if p.get(\"pattern_type\") == \"prebuilt\" and not p.get(\"pattern_name\"):\n            problems.append(f\"prebuilt pattern missing pattern_name: {p}\")\n    return problems","typeGuard":"from typing import TypedDict, Literal\n\nclass PrebuiltPattern(TypedDict):\n    pattern_type: Literal[\"prebuilt\"]\n    pattern_name: str\n    action: str\n\ndef is_valid_prebuilt(entry: dict) -> bool:\n    return (\n        entry.get(\"pattern_type\") == \"prebuilt\"\n        and isinstance(entry.get(\"pattern_name\"), str)\n        and bool(entry[\"pattern_name\"].strip())\n    )","tryCatchPattern":null,"preventionTips":["Copy the exact pattern_name from the prebuilt catalog in the repo — names are case-sensitive identifiers.","Remember `name` labels a pattern; only pattern_name selects a prebuilt one.","Add the pattern lint to CI config validation."],"tags":["configuration","validation","regex","content-filter"],"backgroundTag":"missing-config-field","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}