Strip the category name rather than the finished tag

Normalizing the assembled tag only reaches whitespace at its ends, so a
category registered as "vae " was fixed while one registered as " loras" was
not: its space lands after "model_type:", where the strip that stored names go
through cannot reach it. The entry stayed unmatched and the stale automatic tag
it authorises removing survived.

Stripping the name before the tag is built covers both, and leaves the
vocabulary clean by construction rather than cleaned afterwards.
This commit is contained in:
Simon Pinfold
2026-08-18 12:25:33 -07:00
parent e0774d0925
commit 5d3a0d5e4e
2 changed files with 24 additions and 17 deletions

View File

@@ -3,7 +3,6 @@ from pathlib import Path
from typing import Literal
import folder_paths
from app.assets.helpers import normalize_tags
_NON_MODEL_FOLDER_NAMES = frozenset({"configs", "custom_nodes"})
@@ -331,10 +330,11 @@ def get_path_derived_tag_vocabulary() -> set[str]:
vocabulary = {"input", "output", "temp", "models"}
vocabulary.update(_KNOWN_SUBFOLDER_TAGS)
for folder_name, _bases, _extensions in get_comfy_models_folders():
vocabulary.add(f"model_type:{folder_name}")
# Stored names reach the database through normalize_tags, so an un-normalized
# entry would never match the tag it exists to authorise removing.
return set(normalize_tags(list(vocabulary)))
# Strip the name, not the finished tag: whitespace landing after
# "model_type:" survives the strip that stored names are put through,
# so the entry would never match the tag it authorises removing.
vocabulary.add(f"model_type:{folder_name.strip()}")
return vocabulary
def get_name_and_tags_from_asset_path(file_path: str) -> tuple[str, list[str]]:

View File

@@ -392,19 +392,26 @@ class TestTagReprojection:
tags={"model_type:loras": "automatic"},
)
with patch(
"app.assets.services.path_utils.get_comfy_models_folders",
return_value=[
("checkpoints", [str(comfy_dirs["checkpoints"])], {".safetensors"}),
("loras ", [str(comfy_dirs["loras"])], {".safetensors"}),
],
):
reproject_derived_state()
# Leading whitespace lands after "model_type:", where a strip of the
# finished tag cannot reach it; trailing whitespace a strip would catch.
for registered in (" loras", "loras "):
with patch(
"app.assets.services.path_utils.get_comfy_models_folders",
return_value=[
(
"checkpoints",
[str(comfy_dirs["checkpoints"])],
{".safetensors"},
),
(registered, [str(comfy_dirs["loras"])], {".safetensors"}),
],
):
reproject_derived_state()
assert "model_type:loras" not in _tags(session, "ref-1"), (
"a category name with stray whitespace must not smuggle an entry "
"past the vocabulary and leave the stale tag in place"
)
assert "model_type:loras" not in _tags(session, "ref-1"), (
f"a category registered as {registered!r} must not smuggle an "
"entry past the vocabulary and leave the stale tag in place"
)
def test_automatic_tag_outside_the_vocabulary_is_left_alone(
self, session, comfy_dirs