{"record":{"id":"06ea0bee844794b5","repo":"BerriAI/litellm","slug":"invalid-file-type-allowed-types-join-allow","errorCode":null,"errorMessage":"Invalid file type. Allowed types: {', '.join(allowed_extensions)}","messagePattern":"Invalid file type\\. Allowed types: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py","lineNumber":1562,"sourceCode":"@router.post(\n    \"/upload/logo\",\n    tags=[\"UI Theme Settings\"],\n    dependencies=[Depends(user_api_key_auth)],\n)\nasync def upload_logo(file: UploadFile = File(...)):\n    \"\"\"\n    Upload a custom logo for the admin UI.\n    Accepts image files (PNG, JPG, JPEG, SVG) and stores them for use in the UI.\n    \"\"\"\n    import os\n    from pathlib import Path\n\n    # Validate file type\n    allowed_extensions: Final = {\".png\", \".jpg\", \".jpeg\", \".svg\"}\n    file_extension: Final = Path(file.filename or \"\").suffix.lower()\n\n    if file_extension not in allowed_extensions:\n        raise HTTPException(\n            status_code=400,\n            detail=f\"Invalid file type. Allowed types: {', '.join(allowed_extensions)}\",\n        )\n\n    # Validate file size (max 5MB)\n    file_content: Final = await file.read()\n    if len(file_content) > 5 * 1024 * 1024:  # 5MB\n        raise HTTPException(status_code=400, detail=\"File size too large. Maximum size is 5MB.\")\n\n    # Create uploads directory if it doesn't exist\n    current_dir: Final = os.path.dirname(os.path.abspath(__file__))\n    upload_dir: Final = os.path.join(current_dir, \"..\", \"uploads\")\n    os.makedirs(upload_dir, exist_ok=True)\n\n    # Generate unique filename\n    from litellm._uuid import uuid\n\n    unique_filename: Final = f\"logo_{uuid.uuid4().hex}{file_extension}\"","sourceCodeStart":1544,"sourceCodeEnd":1580,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py#L1544-L1580","documentation":"File-type guard in the logo upload endpoint: the uploaded file's extension is not one of .png/.jpg/.jpeg/.svg. The logo is stored and served by the admin UI, so arbitrary file types are rejected up front; renaming a file to a listed extension does not convert it, so content should genuinely be an image of an allowed type.","triggerScenarios":"Thrown at litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py:1562 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Upload a file with one of the listed allowed extensions."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}