windmill-labs/windmill · error

Timed out waiting for job ${id} to complete

Error message

Timed out waiting for job ${id} to complete

What it means

The CLI polls `getCompletedJob` up to MAX_RETRIES times (with 100ms backoff) when waiting for a script run to finish. If the job never reaches a completed state within that window, it gives up with this timeout error. The job may still be running server-side.

Source

Thrown at cli/src/commands/script/script.ts:1491

      if (completedJob.success === false) {
        process.exitCode = 1;
      }

      const result = completedJob.result ?? {};
      if (opts.silent) {
        console.log(JSON.stringify(result));
      } else {
        log.info(JSON.stringify(result, null, 2));
      }

      break;
    } catch {
      retries++;
      await new Promise((resolve) => setTimeout(resolve, 100));
    }
  }
  if (retries >= MAX_RETRIES) {
    throw new Error(`Timed out waiting for job ${id} to complete`);
  }
}

export async function track_job(workspace: string, id: string) {
  try {
    const result = await wmill.getCompletedJob({ workspace, id });

    log.info(result.logs);
    log.info("\n");
    log.info(colors.bold.underline.green("Job Completed"));
    log.info("\n");
    return;
  } catch {
    /* ignore */
  }

  log.info(colors.yellow("Waiting for Job " + id + " to start..."));

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-run with the job ID visible via `wmill job show <id>` or the UI to check the job's real status.
  2. Check that workers are running and not saturated (queue depth in the UI).
  3. Split a long-running script into smaller steps or increase its timeout/limits.
  4. Retry the run; if jobs repeatedly hang, inspect worker logs for crashes.
Defensive patterns

Strategy: try-catch

Validate before calling

const job = await wmill.getJob({ workspace, id });
console.log('Job currently:', job.running ? 'running' : job.type); // sanity-check before waiting

Try / catch

try {
  const result = await wmill.script.run(path, { wait: true });
} catch (e) {
  if (String(e.message).startsWith('Timed out waiting for job')) {
    const id = e.message.match(/job (\S+) /)?.[1];
    console.error(`CLI gave up; job ${id} may still be running — check 'wmill job show ${id}'.`);
  }
  throw e;
}

Prevention

When it happens

Trigger: `wmill script run --wait` (or track) against a long-running script, or a job stuck in queue because all workers are busy/down; polls exhaust MAX_RETRIES at ~100ms intervals.

Common situations: A script that takes longer than the CLI's fixed polling budget (heavy data processing, LLM calls); no dedicated worker online so the job sits queued; worker crashed mid-run leaving the job in a non-terminal state.

Understand the failure class

Related errors


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