Skip to content

galaxy-tool-cache add fails on stock/built-in tool ids (blocks version lookup in per-step loop) #323

Description

@jmchilton

Posted by Claude (AI assistant) on behalf of @jmchilton — not authored by them personally.

Why this matters for Foundry

The per-step Galaxy authoring loop (advance-galaxy-draft-stepsummarize-galaxy-toolimplement-galaxy-tool-step) needs concrete tool_version + ports for stock/built-in Galaxy tools (Filter1, sort1, Cut1, Show beginning1, Show tail1, collection ops, …). The intended resolution is the same galaxy-tool-cache flow used for Tool Shed tools, just with a bare tool_id instead of owner~repo~tool_id.

In a recent emulated INTERVIEW→GALAXY run that resolution path didn't fire and the agent hallucinated versions: Show beginning1 pinned 1.0.0 (cached real: 1.0.2), Show tail1 1.0.0 (real: 1.0.1). The wrong pins validated green locally (the run's shed-only --cache-dir skipped built-in tool_state) and only surfaced at terminal gxwf validate as a confusing "not in cache".

Root cause: galaxy-tool-cache add is broken for stock/built-in ids upstream (@galaxy-tool-util 1.7.2), so the cache can't be populated the documented way, so the loop has no version source and guesses. (add/summarize are meant to accept bare stock ids — normalizeShortTrsToolId explicitly passes cat1/upload1 through verbatim.)

What works today (verified)

With a cache already populated (locally worked-around), stock tools resolve fine with the bare id:

  • galaxy-tool-cache list --json — default cache enumerates stock + shed tools with versions (the version-discovery surface). e.g. Filter1 1.1.1, sort1 1.2.0, Cut1 1.0.2, Show beginning1 1.0.2, Show tail1 1.0.1.
  • galaxy-tool-cache summarize "Show beginning1" --tool-version 1.0.2 → full galaxy-tool-summary manifest (parsed_tool ports/datatypes, source.kind: local). Verified for all five tools above.
  • summarize requires --tool-version (no auto-default even when exactly one version is cached): summarize Cut1No version specified for tool: Cut1.

So the consumer side (summarize / list) is fine on bare stock ids. The gap is populating the cache via add.

The bug: add on a stock id

$ galaxy-tool-cache add Filter1 --cache-dir $TMP
TRS latest-version lookup failed for Filter1 on https://toolshed.g2.bx.psu.edu:
  TRS versions request to https://toolshed.g2.bx.psu.edu/api/ga4gh/trs/v2/tools/Filter1/versions failed: 500 Internal Server Error
Error: No version available for tool: Filter1
    at ToolInfoService.getToolInfo (.../@galaxy-tool-util/core/dist/tool-info.js:40:23)
    ... (unhandled throw, Node crash)

Root-cause chain (@galaxy-tool-util/core 1.7.2 → upstream jmchilton/galaxy-tool-util-ts)

  1. Stock coords are pinned to the ToolShed. cache/tool-cache.js#resolveToolCoordinates: a stock id has no /repos/ and fails normalizeShortTrsToolId (not owner~repo~tool), so it falls through to toolshedUrl = defaultToolshedUrl, trsToolId = <id> verbatim, version = toolVersion ?? null. (Also yields a malformed readableId like toolshed.g2.bx.psu.edu/repos/Filter1.) Stock tools live in a Galaxy instance, not the shed — this is the wrong source.
  2. Version resolution only queries the ToolShed TRS. tool-info.js#getToolInfo: when version === null it calls resolveLatestVersion(toolshedUrl, trsToolId) → TRS …/api/ga4gh/trs/v2/tools/<id>/versions. For a stock id that 500s → returns nullthrow new Error("No version available for tool: <id>"). A stock tool's version can only come from Galaxy, which is never consulted for version resolution.
  3. No Galaxy source registered without --galaxy-url. ToolInfoService constructor only pushes a {type:"galaxy"} source when opts.galaxyUrl is set; otherwise sources = [toolshed] only. So even past version resolution there's no viable fetch source for a stock id by default. (fetchFromGalaxy(url, toolId, version)<galaxy>/api/tools/<toolId>/parsed is the path that should serve it.)
  4. Error-handling mismatch → unhandled crash. cli/commands/add.js guards result === null ("Failed to fetch tool", exitCode=1), but getToolInfo throws on no-version, so the throw escapes the guard → Node stack-trace crash (and process.exitCode left 0).

Intended behavior

add "<stock_id>" (with a Galaxy source — a configured/default instance, and/or --galaxy-url) should fetch <galaxy>/api/tools/<stock_id>/parsed, resolve the version from Galaxy, and cache it (source: galaxy/local), so summarize/list/schema work with the bare id. The local workaround pre-seeds the cache from a Galaxy tree (→ source: local), confirming the fetched shape is correct.

Proposed upstream fixes (galaxy-tool-util-ts)

  • Recognize stock/built-in ids (no /repos/, no ~) and route them to a Galaxy source for both version resolution and fetch — not the ToolShed TRS.
  • Let version resolution fall back to the Galaxy instance (/api/tools/<id> version) when the shed has no entry, instead of throwing.
  • Make stock add usable without --galaxy-url (default/configured Galaxy) or fail fast with a clear "stock tool requires a Galaxy source (--galaxy-url)" message.
  • Fix the throw-vs-null contract between getToolInfo and add.js so failures exit cleanly (exitCode=1, no stack trace).

Foundry-side follow-up (after add is fixed upstream)

Harden the Tool-Shed-only framing so the loop resolves stock tools instead of guessing:

  • content/cli/galaxy-tool-cache/summarize.md — document bare stock-id support; --tool-version required.
  • New content/cli/galaxy-tool-cache/list.md — version-discovery surface; default cache carries stock tools.
  • content/cli/galaxy-tool-cache/add.md — stock ids aren't on the shed; populate from a Galaxy source.
  • Molds summarize-galaxy-tool, advance-galaxy-draft-step (step 2), implement-galaxy-tool-step (step 2) — add a built-in branch: discover version via list, populate via add (Galaxy source), summarize via bare id + --tool-version; never hand-guess a stock version.
  • Optionally strengthen draft-validate --concrete to resolve built-ins against the default cache so a guessed version can't validate green.

Env: @galaxy-tool-util/cli + @galaxy-tool-util/core 1.7.2 (vendored in node_modules), Node 25.6.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions