BerriAI/litellm · error · ValueError
Invalid format: file must contain 'blocked_words' key with l
Error message
Invalid format: file must contain 'blocked_words' key with list of words
What it means
ValueError raised while loading the blocked-words file: yaml.safe_load() succeeded but the result is either not a dict at all (empty file, or a top-level list) or a dict without the required 'blocked_words' key. The loader expects the exact schema blocked_words: [{keyword, action, description?}].
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py:795
Load blocked words from a YAML file.
Args:
file_path: Path to YAML file containing blocked_words list
Expected format:
```yaml
blocked_words:
- keyword: "sensitive_term"
action: "BLOCK"
description: "Optional description"
```
"""
try:
with open(file_path, "r") as f:
data: Final = yaml.safe_load(f)
if not isinstance(data, dict) or "blocked_words" not in data:
raise ValueError("Invalid format: file must contain 'blocked_words' key with list of words")
for word_data in data["blocked_words"]:
if not isinstance(word_data, dict) or "keyword" not in word_data or "action" not in word_data:
verbose_proxy_logger.warning("Skipping invalid word entry: %s", word_data)
continue
keyword = word_data["keyword"].lower()
action = ContentFilterAction(word_data["action"])
description = word_data.get("description")
self.blocked_words[keyword] = (action, description)
verbose_proxy_logger.info("Loaded %s blocked words from %s", len(data["blocked_words"]), file_path)
except FileNotFoundError:
raise FileNotFoundError(f"Blocked words file not found: {file_path}")
except Exception as e:
raise Exception(f"Error loading blocked words file {file_path}: {e}")
View on GitHub (pinned to 77b7c6c40c)
Solutions
- Restructure the file to the expected schema with a top-level blocked_words list.
- Each entry needs at least keyword and action (entries missing them are skipped with a warning, not an error).
- Validate the file locally before deploy: python -c "import yaml,sys; d=yaml.safe_load(open(sys.argv[1])); assert isinstance(d,dict) and 'blocked_words' in d" yourfile.yaml.
- Confirm you pointed blocked_words_file at a blocked-words file, not a category/policy template.
Example fix
# before (wrong root key)
words:
- keyword: sensitive_term
action: BLOCK
# after
blocked_words:
- keyword: sensitive_term
action: BLOCK
description: optional note Defensive patterns
Strategy: validation
Validate before calling
# Validate the blocked-words file schema before the proxy loads it
import yaml
def lint_blocked_words_file(path: str) -> list[str]:
data = yaml.safe_load(open(path)) or {}
if not isinstance(data, dict) or "blocked_words" not in data:
return [f"{path}: root must be a mapping with a 'blocked_words' list"]
problems = []
for i, w in enumerate(data["blocked_words"]):
if not isinstance(w, dict) or "keyword" not in w or "action" not in w:
problems.append(f"{path}: entry #{i} missing keyword/action (will be skipped)")
return problems Type guard
from typing import Any
def is_valid_blocked_words_doc(doc: Any) -> bool:
"""True when the parsed YAML matches the expected {blocked_words: [...]} shape."""
return (
isinstance(doc, dict)
and isinstance(doc.get("blocked_words"), list)
and all(
isinstance(w, dict) and "keyword" in w and "action" in w
for w in doc["blocked_words"]
)
) Prevention
- The root key is exactly 'blocked_words' — not words/blocklist/blocked.
- Point blocked_words_file only at blocked-words files; category and policy templates have different schemas.
- Commit a validated example file and lint all changes with the check above.
When it happens
Trigger: blocked_words_file points at a YAML file whose root is a list or empty, or whose root key is named differently (words:, blocklist:, blocked:), so `isinstance(data, dict) and 'blocked_words' in data` fails.
Common situations: Hand-written YAML using an intuitive-but-wrong root key; passing a category/policy template file to blocked_words_file; an empty file created as a placeholder; truncation during deploy.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Error loading blocked words file {file_path}: {e}
- Content Filter: guardrail_name is required
- pattern_name is required for prebuilt patterns
- pattern is required for regex patterns
- Unknown pattern_type: {pattern_config.pattern_type}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/932fd1180569ca8f.
Report an issue: GitHub.