windmill-labs/windmill · error

Network error: Could not connect to Windmill server at ${wor

Error message

Network error: Could not connect to Windmill server at ${workspace.remote}

What it means

requireLogin's whoami probe failed with a network-level error (fetch could not reach the server at the workspace's remote URL): the instance is down, the URL is wrong, or DNS/TLS/proxy is failing — it is not an auth failure.

Source

Thrown at cli/src/core/auth.ts:80

  // Import resolveWorkspace to avoid circular dependency at module level
  const { resolveWorkspace } = await import("./context.ts");
  const workspace = await resolveWorkspace(opts);

  let token = await tryGetLoginInfo(opts);

  if (!token) {
    token = workspace.token;
  }

  setClient(token, workspace.remote.substring(0, workspace.remote.length - 1));

  try {
    return await fetchWhoami(workspace.workspaceId);
  } catch (error) {
    // Check for network errors and provide clearer messages
    const errorMsg = error instanceof Error ? error.message : String(error);
    if (errorMsg.includes('fetch') || errorMsg.includes('connection') || errorMsg.includes('ECONNREFUSED') || errorMsg.includes('refused')) {
      throw new Error(`Network error: Could not connect to Windmill server at ${workspace.remote}`);
    }

    // If the user explicitly provided credentials via flags, fail immediately
    // rather than falling back to interactive login — they expect their explicit
    // credentials to work and should fix them if they don't.
    if (opts.token || opts.baseUrl) {
      const isApiError = error && typeof error === "object" &&
        "name" in error && (error as { name: unknown }).name === "ApiError";
      if (isApiError) {
        const status = (error as { status?: number }).status;
        const body = (error as { body?: unknown }).body;
        let bodyStr = typeof body === "object" && body !== null
          ? JSON.stringify(body)
          : String(body ?? "").trim();
        // Strip backend source-file refs like "(flows.rs:1400)" or
        // "@scopes.rs:509" from the surfaced message — same pattern used in
        // main.ts for ApiError display.
        bodyStr = bodyStr.replace(/\s*[@(]\w+\.rs:\d+[:\d]*\)?/g, "");

View on GitHub (pinned to e474e8803c)

Solutions

  1. Verify the instance URL with curl or a browser.
  2. Check that the Windmill server is running and reachable from this machine.
  3. Inspect proxies, VPN, and TLS certificates if the URL is correct.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at cli/src/core/auth.ts:80 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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