Compare commits

...

2 Commits

Author SHA1 Message Date
JSap0914
8eb93ff736
Merge fe89d39c1b into 7f287b705e 2026-07-05 02:32:01 -07:00
JSap0914
fe89d39c1b Fix get_filename_list crash when a cached model folder is deleted
cached_filename_list_ probes os.path.getmtime() for every directory
recorded while the filename cache was built, including subfolders. If
one of those folders is removed at runtime (e.g. the user deletes a
model folder), getmtime() raises FileNotFoundError, which propagates
out of get_filename_list() and breaks model listing instead of simply
rebuilding the cache.

Treat an inaccessible tracked folder as a stale-cache signal and return
None so the list is rebuilt.
2026-06-16 12:35:23 +09:00
2 changed files with 52 additions and 1 deletions

View File

@ -473,7 +473,12 @@ def cached_filename_list_(folder_name: str) -> tuple[list[str], dict[str, float]
for x in out[1]:
time_modified = out[1][x]
folder = x
if os.path.getmtime(folder) != time_modified:
try:
if os.path.getmtime(folder) != time_modified:
return None
except OSError:
# A tracked folder was deleted or became inaccessible; treat the
# cache as stale so it gets rebuilt instead of raising.
return None
folders = folder_names_and_paths[folder_name]

View File

@ -0,0 +1,46 @@
import os
import shutil
import tempfile
import pytest
import folder_paths
@pytest.fixture
def model_folder():
"""Register a temporary model category with a tracked subfolder."""
folder_name = "cache_invalidation_test_cat"
with tempfile.TemporaryDirectory() as base:
category = os.path.join(base, "category")
subfolder = os.path.join(category, "sub")
os.makedirs(subfolder)
open(os.path.join(category, "a.safetensors"), "w").close()
open(os.path.join(subfolder, "b.safetensors"), "w").close()
folder_paths.folder_names_and_paths[folder_name] = (
[category],
{".safetensors"},
)
try:
yield folder_name, category, subfolder
finally:
folder_paths.folder_names_and_paths.pop(folder_name, None)
folder_paths.filename_list_cache.pop(folder_name, None)
folder_paths.cache_helper.clear()
def test_rebuilds_when_tracked_subfolder_deleted(model_folder):
folder_name, _category, subfolder = model_folder
# Populate the filename cache, which records the mtime of every subfolder.
initial = folder_paths.get_filename_list(folder_name)
assert sorted(initial) == ["a.safetensors", "sub/b.safetensors"]
# Remove a tracked subfolder at runtime (e.g. user deletes a model folder).
shutil.rmtree(subfolder)
# The cache must be treated as stale and rebuilt, not crash with
# FileNotFoundError when probing the deleted folder's mtime.
refreshed = folder_paths.get_filename_list(folder_name)
assert refreshed == ["a.safetensors"]