From db38ad80e680a73ae0f48b503826c6a09207435d Mon Sep 17 00:00:00 2001 From: Will Miao Date: Mon, 14 Sep 2026 11:05:12 +0800 Subject: [PATCH] fix(nodes): snapshot scanner cache before iterating on executor thread Node code reads cache.raw_data while MetadataSyncService may mutate it from a background thread; iterate over a list() snapshot to avoid a possible 'list changed size during iteration' RuntimeError. --- py/nodes/checkpoint_loader.py | 4 ++-- py/nodes/save_image.py | 2 +- py/nodes/unet_loader.py | 4 ++-- py/nodes/utils.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/py/nodes/checkpoint_loader.py b/py/nodes/checkpoint_loader.py index 8fdb77dc..8fc819df 100644 --- a/py/nodes/checkpoint_loader.py +++ b/py/nodes/checkpoint_loader.py @@ -78,7 +78,7 @@ class CheckpointLoaderLM: # Filter only checkpoint type (not diffusion_model) and format names names = [] - for item in cache.raw_data: + for item in list(cache.raw_data): if item.get("sub_type") == "checkpoint": file_path = item.get("file_path", "") # Only offer models that still exist on disk so ComfyUI @@ -126,7 +126,7 @@ class CheckpointLoaderLM: cache = await scanner.get_cached_data() base_models = set() - for item in cache.raw_data: + for item in list(cache.raw_data): if item.get("sub_type") != "checkpoint": continue base_model = item.get("base_model") diff --git a/py/nodes/save_image.py b/py/nodes/save_image.py index e4c3001e..ee779523 100644 --- a/py/nodes/save_image.py +++ b/py/nodes/save_image.py @@ -601,7 +601,7 @@ class SaveImageLM: os.path.basename(name), os.path.splitext(os.path.basename(name))[0], ] - for model in getattr(cache, "raw_data", []): + for model in list(getattr(cache, "raw_data", [])): file_name = model.get("file_name") if file_name in candidates: return model diff --git a/py/nodes/unet_loader.py b/py/nodes/unet_loader.py index cffbb8e0..1adff63e 100644 --- a/py/nodes/unet_loader.py +++ b/py/nodes/unet_loader.py @@ -93,7 +93,7 @@ class UNETLoaderLM: # Filter only diffusion_model type and format names names = [] - for item in cache.raw_data: + for item in list(cache.raw_data): if item.get("sub_type") == "diffusion_model": file_path = item.get("file_path", "") # Only offer models that still exist on disk so ComfyUI @@ -141,7 +141,7 @@ class UNETLoaderLM: cache = await scanner.get_cached_data() base_models = set() - for item in cache.raw_data: + for item in list(cache.raw_data): if item.get("sub_type") != "diffusion_model": continue base_model = item.get("base_model") diff --git a/py/nodes/utils.py b/py/nodes/utils.py index 8d6b1c2c..a5f331b9 100644 --- a/py/nodes/utils.py +++ b/py/nodes/utils.py @@ -156,7 +156,7 @@ def _find_missing_loras(names: list[str]) -> list[str]: lookup = {} basename_candidates = {} - for item in cache.raw_data: + for item in list(cache.raw_data): file_path = item.get("file_path") if not file_path: continue