{"record":{"id":"612ff331cd08e9d3","repo":"BerriAI/litellm","slug":"file-not-found-banned-keywords-list-banned-keywo","errorCode":null,"errorMessage":"File not found. banned_keywords_list={banned_keywords_list}","messagePattern":"File not found\\. banned_keywords_list=(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"enterprise/enterprise_hooks/banned_keywords.py","lineNumber":42,"sourceCode":"    # Class variables or attributes\n    def __init__(self):\n        banned_keywords_list = litellm.banned_keywords_list\n\n        if banned_keywords_list is None:\n            raise Exception(\n                \"`banned_keywords_list` can either be a list or filepath. None set.\"\n            )\n\n        if isinstance(banned_keywords_list, list):\n            self.banned_keywords_list = banned_keywords_list\n\n        if isinstance(banned_keywords_list, str):  # assume it's a filepath\n            try:\n                with open(banned_keywords_list, \"r\") as file:\n                    data = file.read()\n                    self.banned_keywords_list = data.split(\"\\n\")\n            except FileNotFoundError:\n                raise Exception(\n                    f\"File not found. banned_keywords_list={banned_keywords_list}\"\n                )\n            except Exception as e:\n                raise Exception(\n                    f\"An error occurred: {str(e)}, banned_keywords_list={banned_keywords_list}\"\n                )\n\n    def print_verbose(self, print_statement, level: Literal[\"INFO\", \"DEBUG\"] = \"DEBUG\"):\n        if level == \"INFO\":\n            verbose_proxy_logger.info(print_statement)\n        elif level == \"DEBUG\":\n            verbose_proxy_logger.debug(print_statement)\n\n        if litellm.set_verbose is True:\n            print(print_statement)  # noqa\n\n    def test_violation(self, test_str: str):\n        for word in self.banned_keywords_list:","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/enterprise/enterprise_hooks/banned_keywords.py#L24-L60","documentation":"In the OpenAI image-variations handler, the async preparation step (transforming the request via the provider transformation layer) is wrapped in a catch-all: any exception raised while building the request (param validation errors like 'Parameter ... is not supported', encoding failures of the input image, invalid API base) is re-raised as OpenAIError with the upstream status_code (default 500), headers, and text. The literal 'error_text' means the original exception had no .text attribute, so str(e) was used - the real cause is in the wrapped message.","triggerScenarios":"Calling litellm.image_variations() (async path) with an unsupported parameter for the model (which raises in transformation), a corrupted or wrong-format image file, an unwritable/missing api_base, or missing credentials that surface during request preparation rather than the HTTP call.","commonSituations":"Generating variations of dall-e-2 images with dall-e-3-only params; passing PNG bytes where the API expects a valid image the encoder can process; mismatched model names routed to the image_variations endpoint; transformation-layer version drift after litellm upgrades.","solutions":["Catch OpenAIError and read .message - it contains the underlying transformation exception text.","Remove unsupported params or set drop_params=True.","Verify the input image is a valid, readable PNG and the model supports variations (dall-e-2).","Upgrade litellm if the transformation layer changed for your model."],"exampleFix":"# before\nimg = await litellm.aimage_variations(model=\"dall-e-2\", image=open(\"cat.png\",\"rb\"), n=2)\n\n# after\ntry:\n    img = await litellm.aimage_variations(model=\"dall-e-2\", image=open(\"cat.png\",\"rb\"), n=2)\nexcept litellm.exceptions.OpenAIError as e:\n    logger.error(\"image_variations failed: %s\", e.message)\n    raise","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\n\ndef variation_input_ok(path: str) -> bool:\n    p = Path(path)\n    return p.exists() and p.stat().st_size > 0 and p.read_bytes()[:8] == b\"\\x89PNG\\r\\n\\x1a\\n\"","typeGuard":"from litellm.exceptions import OpenAIError\n\ndef is_transform_layer_error(e: BaseException) -> bool:\n    return isinstance(e, OpenAIError) and getattr(e, \"status_code\", 500) == 500 and e.headers is None","tryCatchPattern":"from litellm.exceptions import OpenAIError\n\ntry:\n    img = await litellm.aimage_variations(model=\"dall-e-2\", image=image_bytes, n=2)\nexcept OpenAIError as e:\n    logger.error(\"image_variations failed: %s\", e.message)  # e.message holds the transform-layer cause\n    raise","preventionTips":["Verify the input image is a valid PNG before calling (dall-e-2 variations require PNG).","Pass only params the model supports; prefer drop_params=True for user-driven param dicts.","Log e.message fully - the underlying ValueError text is nested inside the OpenAIError."],"tags":["openai","image-variations","dall-e-2","request-transform","litellm"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}