BerriAI/litellm · error · HTTPException

Content blocked: keyword '{keyword}' detected

Error message

Content blocked: keyword '{keyword}' detected

What it means

HTTPException(400) raised by _handle_blocked_word_match when a blocked word matches with action BLOCK. Blocked words come from litellm_params.blocked_words or blocked_words_file (each entry: keyword, action, optional description); on BLOCK the whole request is rejected, and the description field is appended to the error message when present. On MASK the keyword would be redacted with keyword_redaction_tag instead.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py:1346

    ) -> str:
        """Handle blocked word match detection and action."""
        verbose_proxy_logger.debug("Blocked word '%s' found with action %s", keyword, action)

        if detections is not None:
            blocked_word_detection: Final[BlockedWordDetection] = {
                "type": "blocked_word",
                "keyword": keyword,
                "action": action.value,
                "description": description,
            }
            detections.append(blocked_word_detection)

        if action == ContentFilterAction.BLOCK:
            error_msg = f"Content blocked: keyword '{keyword}' detected"
            if description:
                error_msg += f" ({description})"
            verbose_proxy_logger.warning(error_msg)
            raise HTTPException(
                status_code=400,
                detail={
                    "error": error_msg,
                    "keyword": keyword,
                    "description": description,
                },
            )
        elif action == ContentFilterAction.MASK:
            keyword_pattern_for_masking: Final = self._keyword_to_regex_pattern(keyword)
            text = re.sub(
                keyword_pattern_for_masking,
                self.keyword_redaction_tag,
                text,
                flags=re.IGNORECASE,
            )
            verbose_proxy_logger.info("Masked keyword '%s' in content", keyword)

        return text

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the 400 detail: keyword (and description) name the exact blocked word that fired.
  2. If the word should be redacted rather than rejected, change that entry's action from BLOCK to MASK in the words file/config.
  3. Remove or narrow over-broad keywords that produce false positives.
  4. Handle the 400 client-side as a deterministic rejection and rephrase the input.

Example fix

# before — reject any request mentioning the codename
blocked_words:
  - keyword: project-x
    action: BLOCK

# after — redact it instead
blocked_words:
  - keyword: project-x
    action: MASK
Defensive patterns

Strategy: try-catch

Validate before calling

# Client-side pre-screen against your blocked-words list (case-insensitive)
BLOCKED = {"project-x", "acme-secret"}  # keep in sync with blocked_words_file

def contains_blocked_word(text: str) -> str | None:
    lowered = text.lower()
    for w in BLOCKED:
        if w in lowered:
            return w
    return None

# if w := contains_blocked_word(prompt): reject or scrub locally first

Type guard

from fastapi import HTTPException

def is_blocked_word_exception(exc: HTTPException) -> bool:
    d = exc.detail if isinstance(exc.detail, dict) else {}
    return exc.status_code == 400 and isinstance(d.get("keyword"), str) and "keyword" in str(d.get("error", ""))

Try / catch

try:
    resp = await client.chat.completions.create(**params)
except HTTPException as e:
    if is_blocked_word_exception(e):
        keyword = e.detail["keyword"]
        raise PolicyRejectedError(
            user_message="Your request contains a blocked term.",
            blocked_keyword=keyword,  # internal audit only
        ) from e
    raise

Prevention

When it happens

Trigger: A guarded request's text contains an exact (case-insensitive) keyword listed in blocked_words/blocked_words_file whose action is BLOCK.

Common situations: Compliance word-lists (internal project names, competitor names, profanity) configured with BLOCK; a shared keyword like a common word blocking benign traffic; entries migrated from another tool with the wrong action default.

Related errors


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