{"record":{"id":"95573757177dfc72","repo":"BerriAI/litellm","slug":"an-error-occurred-str-e-banned-keywords-list","errorCode":null,"errorMessage":"An error occurred: {str(e)}, banned_keywords_list={banned_keywords_list}","messagePattern":"An error occurred: (.+?), banned_keywords_list=(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"enterprise/enterprise_hooks/banned_keywords.py","lineNumber":46,"sourceCode":"        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:\n            if word in test_str.lower():\n                raise HTTPException(\n                    status_code=400,\n                    detail={\"error\": f\"Keyword banned. Keyword={word}\"},","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/enterprise/enterprise_hooks/banned_keywords.py#L28-L64","documentation":"LiteLLM re-threw an 'authorization denied for' error from an OpenAI-compatible provider (the custom_llm_provider named in the message, e.g. Predibase) as AuthenticationError. Notably, the mapper actively scrubs bearer tokens out of the message before raising, because some providers (Predibase specifically) echo the raw API key back in the error body.","triggerScenarios":"Calling an OpenAI-compatible provider (e.g. predibase/*) with a token lacking permission for the target model/fine-tune/deployment; wrong tenant token; a bearer key valid but not authorized for that specific resource.","commonSituations":"Using a Predibase key from one organization against another's deployments; token has read but not inference scope; resource name typo causing an authorization check against a nonexistent deployment; secret leakage concern because the provider echoes keys.","solutions":["Verify the token belongs to the same tenant/organization that owns the model or deployment.","Confirm the token has inference permissions, not just dataset/read access.","Check model/deployment names for typos - authorization failures often mask missing resources.","Never log the raw exception from the provider; rely on LiteLLM's already-scrubbed message."],"exampleFix":"# before\nr = litellm.completion(model=\"predibase/my-llama3\", messages=msgs)  # authorization denied\n\n# after: use tenant-correct key and explicit deployment\nr = litellm.completion(\n    model=\"predibase/my-deployment/8b-instruct\",\n    messages=msgs,\n    api_key=os.environ[\"PREDIBASE_API_KEY\"],  # token from the owning tenant\n    api_base=os.environ.get(\"PREDIBASE_API_BASE\"),\n)","handlingStrategy":"try-catch","validationCode":"import os\nif not os.environ.get(\"PREDIBASE_API_KEY\"):\n    raise RuntimeError(\"PREDIBASE_API_KEY required for predibase models\")","typeGuard":"def is_authorization_denied(e: BaseException) -> bool:\n    return isinstance(e, litellm.AuthenticationError) and \"authorization denied\" in str(e)","tryCatchPattern":"try:\n    r = litellm.completion(model=\"predibase/my-model\", messages=msgs)\nexcept litellm.AuthenticationError as e:\n    # message is already bearer-scrubbed by litellm; safe to log\n    logger.error(\"predibase authz denied: %s\", e.message)\n    raise","preventionTips":["Ensure the API token belongs to the tenant that owns the model/deployment.","Log only the LiteLLM exception message - some providers echo raw bearer tokens in errors.","Verify resource names; authorization failures often hide nonexistent deployments."],"tags":["openai-compatible","predibase","authorization","authentication","secret-leak","litellm"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}