diff --git a/lib/galaxy/tool_util/parameters/convert.py b/lib/galaxy/tool_util/parameters/convert.py
index 61f89cd8739..f5e5970f769 100644
--- a/lib/galaxy/tool_util/parameters/convert.py
+++ b/lib/galaxy/tool_util/parameters/convert.py
@@ -289,7 +289,7 @@ def encode_test(
test_collection = cast(JsonTestCollectionDefDict, value)
return adapt_collections(test_collection).model_dump()
elif isinstance(parameter, SelectParameterModel):
- if parameter.multiple and value is not None:
+ if parameter.multiple and value is not None and isinstance(value, (str,)):
return [v.strip() for v in value.split(",")]
else:
return VISITOR_NO_REPLACEMENT
@@ -359,7 +359,7 @@ def _fill_default_for(tool_state: Dict[str, Any], parameter: ToolParameterT) ->
if not parameter.multiple:
tool_state[parameter_name] = parameter.default_value
else:
- tool_state[parameter_name] = None
+ tool_state[parameter_name] = parameter.default_values
elif isinstance(parameter, DrillDownParameterModel):
if parameter_name not in tool_state:
if parameter.multiple:
diff --git a/lib/galaxy/tool_util_models/parameters.py b/lib/galaxy/tool_util_models/parameters.py
index 9d20e3cdbf7..93d6954cc8c 100644
--- a/lib/galaxy/tool_util_models/parameters.py
+++ b/lib/galaxy/tool_util_models/parameters.py
@@ -1175,6 +1175,7 @@ class SelectParameterModel(BaseGalaxyToolParameterModelDefinition):
@property
def default_value(self) -> Optional[str]:
+ assert not self.multiple
if self.options:
for option in self.options:
if option.selected:
@@ -1185,6 +1186,13 @@ class SelectParameterModel(BaseGalaxyToolParameterModelDefinition):
return None
+ @property
+ def default_values(self) -> Optional[List[str]]:
+ assert self.multiple
+ if self.options:
+ return [option.value for option in self.options if option.selected]
+ return None
+
@property
def request_requires_value(self) -> bool:
# API will allow an empty value and just grab the first static option
diff --git a/lib/galaxy_test/api/test_tool_execute.py b/lib/galaxy_test/api/test_tool_execute.py
index 78e0f2d34d7..de8ac3bcca6 100644
--- a/lib/galaxy_test/api/test_tool_execute.py
+++ b/lib/galaxy_test/api/test_tool_execute.py
@@ -681,6 +681,17 @@ def test_select_multiple_does_not_select_first_by_default(
).with_contents_stripped("None")
+@requires_tool_id("gx_select_multiple_one_default")
+def test_select_multiple_does_default_to_select_values_marked_as_selected(
+ required_tools: list[RequiredTool], tool_input_format: DescribeToolInputs
+):
+ empty = tool_input_format.when.any({})
+ for required_tool in required_tools:
+ required_tool.execute.with_inputs(empty).assert_has_single_job.with_output("output").with_contents_stripped(
+ "--ex3"
+ )
+
+
@requires_tool_id("gx_text")
@requires_tool_id("gx_text_optional_false")
def test_null_to_text_tools(required_tools: list[RequiredTool], tool_input_format: DescribeToolInputs):
diff --git a/test/functional/tools/parameters/gx_select_multiple_one_default.xml b/test/functional/tools/parameters/gx_select_multiple_one_default.xml
new file mode 100644
index 00000000000..06e1a0050f9
--- /dev/null
+++ b/test/functional/tools/parameters/gx_select_multiple_one_default.xml
@@ -0,0 +1,35 @@
+
+ > '$output'
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/functional/tools/simple_constructs.xml b/test/functional/tools/simple_constructs.xml
index f72036d7500..850b7faa89a 100644
--- a/test/functional/tools/simple_constructs.xml
+++ b/test/functional/tools/simple_constructs.xml
@@ -59,6 +59,7 @@ echo $drop_select >> '$out_file1' &&
+
diff --git a/test/unit/tool_util/test_parameter_convert.py b/test/unit/tool_util/test_parameter_convert.py
index e66b9526096..1d6da0ccf44 100644
--- a/test/unit/tool_util/test_parameter_convert.py
+++ b/test/unit/tool_util/test_parameter_convert.py
@@ -232,12 +232,14 @@ def test_fill_defaults():
with_defaults = fill_state_for({}, "parameters/gx_select_optional")
assert with_defaults["parameter"] is None
- # Not ideal but matching current behavior
with_defaults = fill_state_for({}, "parameters/gx_select_multiple")
- assert with_defaults["parameter"] is None
+ assert with_defaults["parameter"] == []
with_defaults = fill_state_for({}, "parameters/gx_select_multiple_optional")
- assert with_defaults["parameter"] is None
+ assert with_defaults["parameter"] == []
+
+ with_defaults = fill_state_for({}, "parameters/gx_select_multiple_one_default")
+ assert with_defaults["parameter"] == ["--ex3"]
# Do not fill in dynamic defaults... these require a Galaxy runtime.
with_defaults = fill_state_for({}, "remove_value", partial=True)