windmill-labs/windmill · error

GET ${path} -> ${resp.status}

Error message

GET ${path} -> ${resp.status}

What it means

The sync job-polling helper listJobs() performs a raw fetch against the Windmill API (OpenAPI.BASE + path) with auth headers and throws 'GET <path> -> <status>' when the HTTP response is not ok. It surfaces non-2xx statuses (401 unauthorized, 404 wrong workspace/path, 5xx server errors) that the generated OpenAPI client would otherwise wrap, during the flow runs polling done by sync.

Source

Thrown at cli/src/commands/sync/sync.ts:4555

  workspaceId: string,
  sinceIso: string,
  changedPaths: string[],
): Promise<{ pending: number; failed: { path: string; error?: string }[] }> {
  // A dependency job's script_path has no file extension; changed paths do.
  const belongsToPush = (scriptPath?: string) =>
    !!scriptPath &&
    changedPaths.some(
      (p) => p === scriptPath || p.startsWith(scriptPath + "."),
    );
  // Raw fetch: the checked-in generated client predates the `created_after` /
  // `success` filters on the job list routes (see the `apiGet` note in
  // pipeline.ts).
  const listJobs = async (path: string): Promise<unknown[]> => {
    const { OpenAPI } = await import("../../../gen/index.ts");
    const resp = await fetch(`${OpenAPI.BASE}${path}`, {
      headers: { ...getHeaders(), Authorization: `Bearer ${OpenAPI.TOKEN}` },
    });
    if (!resp.ok) throw new Error(`GET ${path} -> ${resp.status}`);
    return (await resp.json()) as unknown[];
  };
  try {
    const since = encodeURIComponent(sinceIso);
    const [queued, completed] = await Promise.all([
      listJobs(
        `/w/${workspaceId}/jobs/queue/list?job_kinds=dependencies&created_after=${since}`,
      ),
      listJobs(
        `/w/${workspaceId}/jobs/completed/list?job_kinds=dependencies&created_after=${since}&success=false`,
      ),
    ]);
    const pending = (queued as { script_path?: string }[]).filter((j) =>
      belongsToPush(j.script_path),
    ).length;
    const failed = (completed as { script_path?: string; result?: unknown }[])
      .filter((j) => belongsToPush(j.script_path))
      .map((j) => ({

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the status in the message: 401 → re-authenticate (`wmill auth login` or refresh token); 404 → verify workspace and base URL; 5xx → check server health/logs and retry
  2. Re-run the sync command after restoring auth or server availability
  3. Check REMOTE/base-url configuration — a proxy returning 502 means the backend is down or the port is wrong
  4. If 429, back off and retry later; reduce polling frequency if you control the client

Example fix

// before (no retry)
const jobs = await listJobs(path);
// after
try {
  const jobs = await listJobs(path);
} catch (e) {
  if (String(e).includes('-> 5')) await sleep(2000), retry();
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const resp = await fetch(`${OpenAPI.BASE}${jobsPath}`, { method: 'HEAD', headers: getHeaders() });
if (!resp.ok) throw new Error(`API unavailable: ${resp.status} — fix auth/URL before syncing`);

Try / catch

try {
  const jobs = await listJobs(path);
} catch (e) {
  const m = /GET .* -> (\d+)/.exec(String(e));
  const status = m?.[1];
  if (status === '401') reauth();
  else if (status?.startsWith('5') || status === '429') await backoffRetry();
  else throw e;
}

Prevention

When it happens

Trigger: `wmill sync` background polling calls listJobs for queued/completed runs and the server returns a non-OK status — expired/invalid token (401), wrong workspace in the URL (404), rate limiting (429), or server error (500/502/503).

Common situations: Token expired mid-sync; remote/server restarted or behind a proxy returning 502; wrong --workspace or --base-url so the jobs endpoint 404s; temporary server overload (5xx) during a long sync.

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/520987e43dab8000. Report an issue: GitHub.