Skip to content

Commit 3ac9a4a

Browse files
committed
LazyToolBox: fall back to default Tool on exact-version miss
The lazy ``get_tool`` returned ``None`` when an indexed tool was queried at a version not present in ``entries_by_version`` and ``exact=True``. The eager toolbox in that situation falls through to the lineage path and returns ``rval[-1]`` (the latest available version), regardless of ``exact`` — its loop only ``continue``s on ``exact`` when the tool *id* is unknown, not when the version is missing. This difference broke ``ToolModule.__init__`` during workflow upload for any workflow pinned to a tool_version we no longer ship. The eager flow returned the newest Tool, then ``get_safe_version`` downgraded it to a registered safe-upgrade version (e.g. ``__BUILD_LIST__`` 1.0.0 → 1.1.0 via ``WORKFLOW_SAFE_TOOL_VERSION_UPDATES``). The lazy flow got ``None``, left the step bound to the latest tool, and on invocation the state-vs-tool mismatch raised "Workflow step has upgrade messages". Surfaced by API ``test_run_with_int_parameter_nested`` against build_list 1.0.0; would similarly affect any workflow whose ``WORKFLOW_SAFE_TOOL_VERSION_UPDATES`` entry has a current_version below the latest indexed version.
1 parent 8fdd0ab commit 3ac9a4a

1 file changed

Lines changed: 18 additions & 10 deletions

File tree

lib/galaxy/tools/lazy_toolbox.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,16 +1379,24 @@ def _ver_key(v: str):
13791379
tool = self._load_tool_on_demand(tool_id, tool_version)
13801380
if tool:
13811381
return tool
1382-
# exact=False + a version we don't have should fall back to
1383-
# the default (latest) version. The eager toolbox does this in
1384-
# ``get_tool`` after a ``_tool_versions_by_id`` miss; the lazy
1385-
# path needs to mirror that explicitly so callers like
1386-
# /api/tools/{id}?tool_version=<bogus> still get the latest
1387-
# entry's Tool instead of a 404. Use the default entry's own
1388-
# version (not ``None``) — passing ``None`` falls back to the
1389-
# ``_tools_by_id`` placeholder, which may already hold a
1390-
# different version cached from an earlier load.
1391-
if tool_version and not exact:
1382+
# Version not in the index. Fall back to the default (latest)
1383+
# entry's Tool — not the requested version, but a Tool for the
1384+
# same id. The eager toolbox does this after a
1385+
# ``_tool_versions_by_id`` miss whenever ``tool_id`` is in
1386+
# ``_tools_by_id``, regardless of ``exact``: the for-loop in
1387+
# ``AbstractToolBox.get_tool`` only ``continue``s for
1388+
# ``exact`` when the id itself is unknown. Without this
1389+
# fallback, ``ToolModule.__init__`` invoked at workflow-upload
1390+
# time (which calls ``get_tool(..., exact=True)``) gets
1391+
# ``None`` for any workflow pinned to a tool_version we no
1392+
# longer ship — eager would have returned the lineage-newest
1393+
# Tool, then ``get_safe_version`` would have downgraded it to
1394+
# the safe-upgrade version (e.g. ``__BUILD_LIST__`` 1.0.0 →
1395+
# 1.1.0 via ``WORKFLOW_SAFE_TOOL_VERSION_UPDATES``). Returning
1396+
# ``None`` here breaks that path and the workflow ends up
1397+
# bound to the latest version with state shaped for the old
1398+
# version, producing spurious upgrade-message 400s on invoke.
1399+
if tool_version:
13921400
default_entry = self._tool_index.entries.get(tool_id)
13931401
if default_entry is not None:
13941402
default_version = default_entry.version or None

0 commit comments

Comments
 (0)