diff --git a/lib/galaxy/tools/lazy_toolbox.py b/lib/galaxy/tools/lazy_toolbox.py index 836137a1674..497edc6fe04 100644 --- a/lib/galaxy/tools/lazy_toolbox.py +++ b/lib/galaxy/tools/lazy_toolbox.py @@ -791,6 +791,22 @@ class LazyToolBox(ToolBox): "or, for a new Galaxy-internal lib tool, add it to " "galaxy.tools.special_tools.hidden_lib_tool_paths()." ) + data_manager_id = kwds.get("data_manager_id") + if data_manager_id and not entry.data_manager_id: + # ``DataManager._load_tool`` hands the ```` conf + # id through ``load_hidden_tool``. Entries minted before any data + # manager conf covered this tool (install-time self-heal) don't + # carry it, and the materialise path must restore it or + # ``DataManagerTool.exec_after_process`` falls back to the tool + # id and misses the registry. Persist so job-handler processes + # materialising from the shared index see it too. + entry.data_manager_id = data_manager_id + if self._store is not None: + try: + self._store.update_index_entry(entry) + self._store.commit() + except Exception as e: + log.warning("Persisting data_manager_id for %s raised: %s", entry.id, e) # LazyTool is duck-typed against Tool — the eager pipeline (audited # in plans/witty-drifting-clock.md) only consults attributes the # stub forwards from ToolIndexEntry, with mutations stored on diff --git a/test/unit/app/tools/test_lazy_tool.py b/test/unit/app/tools/test_lazy_tool.py index 6676fe49885..a8a3d6df11c 100644 --- a/test/unit/app/tools/test_lazy_tool.py +++ b/test/unit/app/tools/test_lazy_tool.py @@ -356,6 +356,16 @@ def test_create_tool_populates_adhoc_for_existing_file(tmp_path, monkeypatch): box._store.invalidate_index_cache.assert_called() +def test_create_tool_stamps_data_manager_conf_id_on_entry(): + box = _seam_box() + e = _entry(id="dm_tool", tool_type="manage_data") + box._tool_index.entries["dm_tool"] = e + tool = box.create_tool(config_file=None, guid="dm_tool", data_manager_id="test_data_manager") + assert isinstance(tool, LazyTool) + assert e.data_manager_id == "test_data_manager" + box._store.update_index_entry.assert_called_once_with(e) + + def test_create_tool_raises_on_index_miss(): # The populator owns the index — including the Galaxy-internal lib # tools listed in ``galaxy.tools.special_tools.hidden_lib_tool_paths``.