windmill-labs/windmill · error

Couldn't fetch resource types from hub ${hubBaseUrl}: ${(awa

Error message

Couldn't fetch resource types from hub ${hubBaseUrl}: ${(await res1.text())}

What it means

The Windmill CLI's hub resource-type pull step fetches a hub's resource-type listing and throws this when the first list HTTP response is not OK (and not a 401, which gets its own message). The error text embeds the hub base URL and the raw response body so the developer can see the server-side reason.

Source

Thrown at cli/src/commands/hub/hub.ts:75

      log.info("Using hub API secret");
      headers["X-api-secret"] = hubSecret;
    }
  }

  if (uid) {
    headers["X-uid"] = uid;
  }

  let res1 = await fetch(hubBaseUrl + "/resource_types/list", {
    headers,
  });

  if (!res1.ok) {
    if (res1.status === 401) {
      // 401 can only happen on a private hub
      throw new Error("Unauthorized access to private hub: " + hubBaseUrl);
    } else {
      throw new Error(
        "Couldn't fetch resource types from hub " +
          hubBaseUrl +
          ": " +
          (await res1.text())
      );
    }
  }

  let list = (await res1.json()) as HubResourceType[];

  if (list && list.length === 0 && hubBaseUrl !== DEFAULT_HUB_BASE_URL) {
    log.info(
      "No resource types found in private hub, fetching from public hub"
    );
    delete headers["X-api-secret"];
    const res2 = await fetch(DEFAULT_HUB_BASE_URL + "/resource_types/list", {
      headers,
    });

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check the hub URL in the message is reachable and serves /resource_types/list (curl it in a browser)
  2. If using a private hub, verify credentials are set — a 401 is reported separately, so 403/404 usually means wrong URL or missing token scope
  3. Retry if the response body shows a transient 5xx
  4. If behind a corporate proxy, configure proxy env vars so fetch reaches the hub

Example fix

// before
await wmillPull({ hub: "https://hub.windmill.dev/" });
// after
const base = "https://hub.windmill.dev"; // no trailing slash/path typo
const res = await fetch(base + "/resource_types/list");
console.log(res.status, await res.text()); // verify before pulling
Defensive patterns

Strategy: validation

Validate before calling

const res = await fetch(hubBaseUrl + "/resource_types/list");
if (!res.ok) {
  throw new Error(`Hub ${hubBaseUrl} unreachable: ${res.status} ${await res.text()}`);
}

Try / catch

try {
  await pullHubResourceTypes(hubBaseUrl);
} catch (e) {
  if (String(e).includes("Couldn't fetch resource types from hub")) {
    console.error("Check hub URL/availability:", hubBaseUrl, e.message);
  }
}

Prevention

When it happens

Trigger: Running 'wmill hub pull' (resource types branch) against a hub whose /resource_types/list returns a non-ok status other than 401: 404 on a wrong hubBaseUrl path, 403 forbidden, 500 server error, or a proxy/auth gateway rejection.

Common situations: Pointing --hub at a custom or self-hosted hub URL that doesn't serve the expected API path; hub behind a reverse proxy returning HTML error pages; hub service temporarily down; firewall/corporate proxy intercepting the request.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/d97d972c9f890208. Report an issue: GitHub.