fix: gate multiselect validation on schema config, improve error message, add tests
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled

Amp-Thread-ID: https://ampcode.com/threads/T-019dad04-a07a-724b-af4d-fbfe98654fdd
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Jedrzej Kosinski 2026-04-20 19:53:32 -07:00
parent fc51d13beb
commit 711907e6ec
2 changed files with 49 additions and 4 deletions

View File

@ -994,8 +994,8 @@ async def validate_inputs(prompt_id, prompt, item, validated):
combo_options = extra_info.get("options", []) combo_options = extra_info.get("options", [])
else: else:
combo_options = input_type combo_options = input_type
# MultiCombo sends a list of selected values is_multiselect = extra_info.get("multiselect", False)
if isinstance(val, list): if is_multiselect and isinstance(val, list):
invalid_vals = [v for v in val if v not in combo_options] invalid_vals = [v for v in val if v not in combo_options]
else: else:
invalid_vals = [val] if val not in combo_options else [] invalid_vals = [val] if val not in combo_options else []
@ -1014,7 +1014,7 @@ async def validate_inputs(prompt_id, prompt, item, validated):
error = { error = {
"type": "value_not_in_list", "type": "value_not_in_list",
"message": "Value not in list", "message": "Value not in list",
"details": f"{x}: '{invalid_vals}' not in {list_info}", "details": f"{x}: {', '.join(repr(v) for v in invalid_vals)} not in {list_info}",
"extra_info": { "extra_info": {
"input_name": x, "input_name": x,
"input_config": input_config, "input_config": input_config,

View File

@ -1,4 +1,4 @@
from comfy_api.latest._io import MultiCombo from comfy_api.latest._io import Combo, MultiCombo
def test_multicombo_serializes_multi_select_as_object(): def test_multicombo_serializes_multi_select_as_object():
@ -31,3 +31,48 @@ def test_multicombo_serializes_multi_select_with_placeholder_and_chip():
"placeholder": "Select providers", "placeholder": "Select providers",
"chip": True, "chip": True,
} }
def test_combo_does_not_serialize_multiselect():
"""Regular Combo should not have multiselect in its serialized output."""
combo = Combo.Input(
id="choice",
options=["a", "b", "c"],
)
serialized = combo.as_dict()
# Combo sets multiselect=False, but prune_dict keeps False (not None),
# so it should be present but False
assert serialized.get("multiselect") is False
assert "multi_select" not in serialized
def _validate_combo_values(val, combo_options, is_multiselect):
"""Reproduce the validation logic from execution.py for testing."""
if is_multiselect and isinstance(val, list):
return [v for v in val if v not in combo_options]
else:
return [val] if val not in combo_options else []
def test_multicombo_validation_accepts_valid_list():
options = ["a", "b", "c"]
assert _validate_combo_values(["a", "b"], options, True) == []
def test_multicombo_validation_rejects_invalid_values():
options = ["a", "b", "c"]
assert _validate_combo_values(["a", "x"], options, True) == ["x"]
def test_multicombo_validation_accepts_empty_list():
options = ["a", "b", "c"]
assert _validate_combo_values([], options, True) == []
def test_combo_validation_rejects_list_even_with_valid_items():
"""A regular Combo should not accept a list value."""
options = ["a", "b", "c"]
invalid = _validate_combo_values(["a", "b"], options, False)
assert len(invalid) > 0