Tolerate null list elements for optional data parameters

#22617 routed every non-dict/non-instance value in a multiple data
parameter's value list through `_decode_dataset_id`, which raises
`ParameterValueError("invalid dataset id None")` for anything that isn't
an int/digit/16-char id. An unset optional data input connected to a
`multiple="true"` data parameter arrives as a null list element
(`[None]`), so the job failed at preparation with "invalid dataset id
None" instead of running. Before #22617 this path did
`query(HistoryDatasetAssociation).get(None)` -> `None`, so the null was
tolerated and the tool saw no dataset.

Filter `None`/`"None"`/`""` list elements in `DataToolParameter.from_json`
(matching the existing `to_python` behaviour) so null is tolerated as
"no dataset" while genuinely malformed ids are still rejected. This
restores correct execution of workflows that leave an optional data
input unset (the UI submits explicit null for such inputs).
This commit is contained in:
mvdbeek
2026-06-04 09:11:18 +02:00
parent f4d1710fd8
commit 51f9c720df
2 changed files with 16 additions and 0 deletions
+6
View File
@@ -2215,6 +2215,12 @@ class DataToolParameter(BaseDataToolParameter):
),
):
rval.append(single_value)
elif single_value in (None, "None", ""):
# An unset optional data input (e.g. connected to a multiple
# data parameter) arrives as a null list element. Tolerate it
# as "no dataset" the way to_python() filters it, rather than
# treating null as a malformed id (regression from #22617).
continue
else:
pk = _decode_dataset_id(single_value, trans.security, self.name)
rval.append(trans.sa_session.get(HistoryDatasetAssociation, pk))
@@ -45,6 +45,16 @@ class TestDataToolParameter(BaseParameterTestCase):
with pytest.raises(ParameterValueError, match="invalid dataset id"):
self.param.from_json("not-an-id", self.trans)
def test_from_json_multi_tolerates_none(self):
# An unset optional data input connected to a multiple data parameter
# arrives as a null list element; it must be filtered out rather than
# rejected as a malformed id (regression from #22617, surfaced as a
# workflow run erroring on an unset optional data input).
self.multiple = True
self.optional = True
assert self.param.from_json([None], self.trans) == []
assert self.param.from_json(["None"], self.trans) == []
def test_field_filter_on_types(self):
hda1 = MockHistoryDatasetAssociation(name="hda1", id=1)
hda2 = MockHistoryDatasetAssociation(name="hda2", id=2)