TS_CORS_ISSUE

ToolShed CORS — blocker for browser-based tool resolution

Summary

The Galaxy Workflows VS Code extension running in the browser (vscode.dev / github.dev / vscode-test-web) cannot fetch tool metadata from the Galaxy ToolShed because ToolShed responds without an Access-Control-Allow-Origin header. The browser’s same-origin policy then blocks every cross-origin fetch() the in-browser language servers make, even though the requests themselves are valid and succeed from curl / Node.

This is not a bug in the extension. It is a server-side gap in ToolShed. The desktop (Node) extension is unaffected because Node fetch does not enforce CORS.

Evidence

curl against ToolShed returns 200 with JSON:

$ curl -s -o /dev/null -w "%{http_code}\n" \
    "https://toolshed.g2.bx.psu.edu/api/tools/iuc~kraken2~kraken2/versions/2.1.1+galaxy1"
200

The same URL from the in-browser server worker fails:

[DEBUG] toolshed fetch failed (https://toolshed.g2.bx.psu.edu) for
        iuc~kraken2~kraken2: Failed to fetch
        @ .../server/gx-workflow-ls-native/dist/web/nativeServer.js

Failed to fetch / net::ERR_FAILED is the browser surfacing a CORS rejection: the preflight/response has no Access-Control-Allow-Origin, so the response is not readable by the page and the promise rejects.

Confirming it is purely CORS: placing a tiny reverse proxy in front of ToolShed that adds Access-Control-Allow-Origin: * makes every one of these fetches succeed (200) from the browser, with no other change.

What breaks (browser only)

Every feature that needs a live fetch from ToolShed:

Already-cached tools keep working in the browser across reloads because the IndexedDB tool cache (galaxy-tool-cache-v1) persists. This masks the problem: a workspace whose tools were cached in a prior (working) session still validates, while new lookups silently return nothing.

Endpoints that must be CORS-enabled

All under the ToolShed origin (default https://toolshed.g2.bx.psu.edu). These are the request shapes the extension’s @galaxy-tool-util/{core,search} layer issues:

For the browser client a minimal, safe policy is sufficient — these are public, unauthenticated, read-only JSON endpoints:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: *

and a 204 response to OPTIONS preflight on the same paths. No credentials are sent, so Access-Control-Allow-Origin: * (rather than echoing Origin + Allow-Credentials) is appropriate and avoids the credentialed-wildcard restriction.

Workarounds (until ToolShed sets CORS)

  1. CORS reverse proxy (used for the capture/demo work). Forwards all paths to ToolShed and adds the headers above; point the extension at it via galaxyWorkflows.toolShed.url. Dev/demo only — not shippable.

    // minimal node proxy on :8765 -> https://toolshed.g2.bx.psu.edu
    // adds Access-Control-Allow-Origin: *, handles OPTIONS preflight
  2. tool-cache-proxy (galaxy-tool-util package) — a same-origin tool source the web build can hit without CORS. The right long-term answer for hosted web deployments if ToolShed CORS can’t be relied on.

  3. Pre-warm the cache — populate the IndexedDB cache from a context that can reach ToolShed, then operate offline. Brittle; only covers known tools.

Enable CORS on the public read-only ToolShed API (headers above). This unblocks the browser extension directly with no client changes and no proxy. File against the ToolShed (galaxyproject) — it benefits any browser-based ToolShed API consumer, not just this extension.

Caveats / notes