windmill-labs/windmill · error · Error

Failed to push completed jobs: ${e}

Error message

Failed to push completed jobs: ${e}

What it means

When pushing completed jobs, any exception that is not a 'file not found' (which is treated as an optional skip) is rethrown wrapped in this message. It covers both read/parse problems of the file and failures of the importCompletedJobs API call.

Source

Thrown at cli/src/commands/jobs/jobs.ts:215

    if (!Array.isArray(completedJobs)) {
      throw new Error("Completed jobs file must contain an array of jobs");
    }

    const completedResult = await wmill.importCompletedJobs({
      workspace: ws.workspaceId,
      requestBody: completedJobs,
    });

    log.info(colors.green(`Completed jobs: ${completedResult}`));
  } catch (e: any) {
    if (e.code === "ENOENT") {
      log.info(
        colors.yellow(
          `No completed jobs file found at ${completedPath}, skipping`
        )
      );
    } else {
      throw new Error(`Failed to push completed jobs: ${e}`);
    }
  }

  // Push queued jobs
  const queuedPath = opts.queuedFile || "queued_jobs.json";
  try {
    const queuedContent = await readTextFile(queuedPath);
    const queuedJobs = JSON.parse(queuedContent);

    if (!Array.isArray(queuedJobs)) {
      throw new Error("Queued jobs file must contain an array of jobs");
    }

    const queuedResult = await wmill.importQueuedJobs({
      workspace: ws.workspaceId,
      requestBody: queuedJobs,
    });

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check the embedded cause `${e}` in the message for the real error (parse vs API)
  2. Validate the file is valid JSON and an array of correctly shaped job objects before pushing
  3. Run 'wmill whoami' to confirm token/workspace validity and permissions
  4. Test the import with a small file (one job) to isolate payload-schema issues

Example fix

// before: invalid payload shape
[{"path": "f/foo"}]  // server 400: missing required fields
// after: export proper completed-job objects
[{"id": "...", "path": "f/foo", "args": {}, "result": ..., "...": "..."}]
// verify first: cat completed_jobs.json | jq . >/dev/null && wmill jobs push
Defensive patterns

Strategy: try-catch

Validate before calling

const content = await readTextFile(completedPath);
const jobs = JSON.parse(content); // throws early on malformed JSON
if (!Array.isArray(jobs)) throw new Error("Expected array");
// sanity: every entry has the fields the import API requires
for (const j of jobs) {
  if (!j.path) throw new Error("Each completed job needs at least a 'path'");
}

Type guard

function isCompletedJob(v: unknown): v is { path: string; [k: string]: unknown } {
  return typeof v === "object" && v !== null && typeof (v as any).path === "string";
}

Try / catch

try {
  await wmillJobsPush({ completedFile: path });
} catch (e) {
  const msg = String(e);
  if (msg.includes("Failed to push completed jobs")) {
    const cause = msg.split("Failed to push completed jobs: ")[1];
    if (cause?.includes("Unexpected token")) console.error("Malformed JSON in completed_jobs.json");
    else console.error("API import failed:", cause); // check token/workspace/payload
  }
}

Prevention

When it happens

Trigger: completed_jobs.json exists but is unreadable (permissions), invalid JSON (JSON.parse throws), the API call wmill.importCompletedJobs returns an error (bad payload, auth, server 4xx/5xx), or a network failure during the request.

Common situations: Malformed JSON in the export; job payloads not matching the server's expected schema causing a 400; expired/insufficient token; wrong workspace; CI network blips.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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