{"record":{"id":"007870820efccca9","repo":"AUTOMATIC1111/stable-diffusion-webui","slug":"file-cannot-be-fetched-filename-extensions-all","errorCode":null,"errorMessage":"File cannot be fetched: {filename}. Extensions allowed: {allowed_preview_extensions()}.","messagePattern":"File cannot be fetched: (.+?)\\. Extensions allowed: (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"modules/ui_extra_networks.py","lineNumber":108,"sourceCode":"    \"\"\"registers extra networks page for the UI; recommend doing it in on_before_ui() callback for extensions\"\"\"\r\n\r\n    extra_pages.append(page)\r\n    allowed_dirs.clear()\r\n    allowed_dirs.update(set(sum([x.allowed_directories_for_previews() for x in extra_pages], [])))\r\n\r\n\r\ndef fetch_file(filename: str = \"\"):\r\n    from starlette.responses import FileResponse\r\n\r\n    if not os.path.isfile(filename):\r\n        raise HTTPException(status_code=404, detail=\"File not found\")\r\n\r\n    if not any(Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs):\r\n        raise ValueError(f\"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.\")\r\n\r\n    ext = os.path.splitext(filename)[1].lower()[1:]\r\n    if ext not in allowed_preview_extensions():\r\n        raise ValueError(f\"File cannot be fetched: {filename}. Extensions allowed: {allowed_preview_extensions()}.\")\r\n\r\n    # would profit from returning 304\r\n    return FileResponse(filename, headers={\"Accept-Ranges\": \"bytes\"})\r\n\r\n\r\ndef fetch_cover_images(page: str = \"\", item: str = \"\", index: int = 0):\r\n    from starlette.responses import Response\r\n\r\n    page = next(iter([x for x in extra_pages if x.name == page]), None)\r\n    if page is None:\r\n        raise HTTPException(status_code=404, detail=\"File not found\")\r\n\r\n    metadata = page.metadata.get(item)\r\n    if metadata is None:\r\n        raise HTTPException(status_code=404, detail=\"File not found\")\r\n\r\n    cover_images = json.loads(metadata.get('ssmd_cover_images', {}))\r\n    image = cover_images[index] if index < len(cover_images) else None\r","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/ui_extra_networks.py#L90-L126","documentation":"Third guard in fetch_file(): after the file exists and sits in an allowed directory, its extension (splittext lowercased, dot stripped) must be in allowed_preview_extensions(). Preview-serving is intentionally limited to image types, so anything else (.txt, .json, .webp depending on settings) is refused.","triggerScenarios":"Requesting a preview whose extension is not in the allowed set — commonly because the user's Settings > 'Preview image extension' or the built-in allowlist (png/jpg/jpeg/webp as configured) excludes the file they linked, e.g. .avif or extensionless files.","commonSituations":"Users dropping arbitrary files next to models expecting them to be served as previews; browser/OS hiding extensions causing a 'photo.png' that is really 'photo.png.txt'.","solutions":["Rename the preview to a standard extension: .png, .jpg, or .webp","Check Settings for preview/extension allowlist options and reload the UI after changing them","Confirm the real extension with `ls`/file manager — hidden double extensions are the usual culprit"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from modules import ui_extra_networks\ndef ext_allowed(filename):\n    return os.path.splitext(filename)[1].lower()[1:] in ui_extra_networks.allowed_preview_extensions()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Save previews only as png/jpg/webp","Check 'show hidden file extensions' to catch double extensions","Keep metadata about preview paths consistent with actual files"],"tags":["http","validation","extra-networks","preview","file-extension"],"backgroundTag":null,"analyzedSha":"82a973c04367123ae98bd9abdf80d9eda9b910e2","analyzedAt":"2026-08-14T16:46:43.225Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}