AUTOMATIC1111/stable-diffusion-webui · error · ValueError
File cannot be fetched: {filename}. Must be in one of direct
Error message
File cannot be fetched: {filename}. Must be in one of directories registered by extra pages. What it means
Second guard in fetch_file(): the requested filename's absolute path must have one of the registered allowed_dirs (directories declared by extra-network pages via allowed_directories_for_previews()) among its parents. Anything outside those roots — including ../ traversal attempts — is rejected with this ValueError, making it also a path-traversal defense.
Source
Thrown at modules/ui_extra_networks.py:104
return res
def register_page(page):
"""registers extra networks page for the UI; recommend doing it in on_before_ui() callback for extensions"""
extra_pages.append(page)
allowed_dirs.clear()
allowed_dirs.update(set(sum([x.allowed_directories_for_previews() for x in extra_pages], [])))
def fetch_file(filename: str = ""):
from starlette.responses import FileResponse
if not os.path.isfile(filename):
raise HTTPException(status_code=404, detail="File not found")
if not any(Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs):
raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.")
ext = os.path.splitext(filename)[1].lower()[1:]
if ext not in allowed_preview_extensions():
raise ValueError(f"File cannot be fetched: {filename}. Extensions allowed: {allowed_preview_extensions()}.")
# would profit from returning 304
return FileResponse(filename, headers={"Accept-Ranges": "bytes"})
def fetch_cover_images(page: str = "", item: str = "", index: int = 0):
from starlette.responses import Response
page = next(iter([x for x in extra_pages if x.name == page]), None)
if page is None:
raise HTTPException(status_code=404, detail="File not found")
metadata = page.metadata.get(item)
if metadata is None:
View on GitHub (pinned to 82a973c043)
Solutions
- Only request files that live inside a registered extra-networks directory (embeddings/, models/Lora/, etc.)
- If you author an extra-networks page, implement allowed_directories_for_previews() to return your preview dirs so they become fetchable
- For external assets, serve them from your own route instead of trying to use this endpoint
Example fix
# extension authors: register your preview directory
class MyPage(extra_networks_page.ExtraNetworksPage):
def allowed_directories_for_previews(self):
return [os.path.join(my_extension_dir, 'previews')] Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
from modules import ui_extra_networks
def is_fetchable(filename):
p = Path(filename).absolute()
return p.is_file() and any(Path(x).absolute() in p.parents for x in ui_extra_networks.allowed_dirs) Prevention
- Never point preview requests outside registered extra-network directories
- Extension pages must implement allowed_directories_for_previews()
- Treat this ValueError in logs as a signal of probing or misconfigured paths
When it happens
Trigger: A request whose filename resolves outside every allowed root: absolute paths pointing elsewhere on disk (/etc/passwd), or relative paths with enough ../ segments to climb out of the models directory. Also legitimate-looking requests when allowed_dirs is empty because no extra page has registered preview directories yet.
Common situations: Security scanners probing the endpoint; a custom extension registering a page but forgetting allowed_directories_for_previews(); bookmarked/crafted URLs referencing directories that were never registered.
Related errors
- File cannot be fetched: {filename}. Extensions allowed: {all
- Requests not allowed
- Request to local resource not allowed
- global '{module}/{name}' is forbidden
- bad file inside {filename}: {name}
AI-assisted analysis of AUTOMATIC1111/stable-diffusion-webui@82a973c043 (2026-08-14).
Data as JSON: /api/errors/37b57c9bfd66cc8b.
Report an issue: GitHub.