Skip to content

Commit 0908613

Browse files
committed
fix(assets): only extension-matching buckets contribute a loader_path
The model-base match in get_asset_category_and_relative_path ignored each bucket's extension set, so a file inside a registered base whose extension the bucket cannot load (e.g. a .txt uploaded into model_type:checkpoints) advertised a loader_path that no loader list would ever resolve, while the tag side of the same stack already excluded it. Apply the extension check used for backend tags (empty set accepts any extension), keeping loader_path null exactly when no loader can resolve the file.
1 parent 72f239a commit 0908613

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

app/assets/services/path_utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,14 @@ def _compute_relative(child: str, parent: str) -> str:
209209
return "temp", _compute_relative(fp_abs, temp_base)
210210

211211
# 4) models (check deepest matching base to avoid ambiguity)
212+
ext = os.path.splitext(fp_abs)[1].lower()
212213
best: tuple[int, str, str] | None = None # (base_len, bucket, rel_inside_bucket)
213-
for bucket, bases, _exts in get_comfy_models_folders():
214+
for bucket, bases, extensions in get_comfy_models_folders():
215+
# A bucket only lists files within its extension set (empty set
216+
# accepts any extension), so a bucket that cannot load the file
217+
# must not contribute a loader path.
218+
if extensions and ext not in extensions:
219+
continue
214220
for b in bases:
215221
base_abs = os.path.abspath(b)
216222
if not _check_is_within(fp_abs, base_abs):

tests-unit/assets_test/services/test_path_utils.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,42 @@ def test_unregistered_file_under_models_root_has_no_loader_path(self, fake_dirs)
523523
assert compute_logical_path(str(f)) == "models/not_registered/orphan.bin"
524524
assert compute_loader_path(str(f)) is None
525525

526+
def test_extension_mismatch_in_registered_bucket_has_no_loader_path(self, fake_dirs):
527+
# Inside a registered bucket, but the bucket's extension set cannot
528+
# load it: no model_type tag, and no loader path either.
529+
f = fake_dirs["models"] / "notes.txt"
530+
f.touch()
531+
532+
assert compute_logical_path(str(f)) == "models/checkpoints/notes.txt"
533+
assert compute_loader_path(str(f)) is None
534+
535+
def test_shared_base_loader_path_uses_extension_matching_bucket(self, fake_dirs):
536+
shared_root = fake_dirs["models"].parent / "unet"
537+
shared_root.mkdir()
538+
f = shared_root / "wan.gguf"
539+
f.touch()
540+
541+
with patch(
542+
"app.assets.services.path_utils.get_comfy_models_folders",
543+
return_value=[
544+
("diffusion_models", [str(shared_root)], {".safetensors"}),
545+
("unet_gguf", [str(shared_root)], {".gguf"}),
546+
],
547+
):
548+
assert compute_loader_path(str(f)) == "wan.gguf"
549+
550+
def test_match_all_bucket_provides_loader_path_for_any_extension(self, fake_dirs):
551+
custom_root = fake_dirs["models"].parent / "custom_bucket"
552+
custom_root.mkdir()
553+
f = custom_root / "weights.bin"
554+
f.touch()
555+
556+
with patch(
557+
"app.assets.services.path_utils.get_comfy_models_folders",
558+
return_value=[("custom_bucket", [str(custom_root)], set())],
559+
):
560+
assert compute_loader_path(str(f)) == "weights.bin"
561+
526562
def test_extra_path_model_has_loader_path_but_no_logical_path(self, tmp_path: Path):
527563
"""Registered category base outside models_dir (extra_model_paths style).
528564

0 commit comments

Comments
 (0)