{"record":{"id":"b9a414a0a52cac56","repo":"windmill-labs/windmill","slug":"failed-to-push-completed-jobs-e","errorCode":null,"errorMessage":"Failed to push completed jobs: ${e}","messagePattern":"Failed to push completed jobs: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/jobs/jobs.ts","lineNumber":215,"sourceCode":"    if (!Array.isArray(completedJobs)) {\n      throw new Error(\"Completed jobs file must contain an array of jobs\");\n    }\n\n    const completedResult = await wmill.importCompletedJobs({\n      workspace: ws.workspaceId,\n      requestBody: completedJobs,\n    });\n\n    log.info(colors.green(`Completed jobs: ${completedResult}`));\n  } catch (e: any) {\n    if (e.code === \"ENOENT\") {\n      log.info(\n        colors.yellow(\n          `No completed jobs file found at ${completedPath}, skipping`\n        )\n      );\n    } else {\n      throw new Error(`Failed to push completed jobs: ${e}`);\n    }\n  }\n\n  // Push queued jobs\n  const queuedPath = opts.queuedFile || \"queued_jobs.json\";\n  try {\n    const queuedContent = await readTextFile(queuedPath);\n    const queuedJobs = JSON.parse(queuedContent);\n\n    if (!Array.isArray(queuedJobs)) {\n      throw new Error(\"Queued jobs file must contain an array of jobs\");\n    }\n\n    const queuedResult = await wmill.importQueuedJobs({\n      workspace: ws.workspaceId,\n      requestBody: queuedJobs,\n    });\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/jobs/jobs.ts#L197-L233","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the embedded cause `${e}` in the message for the real error (parse vs API)","Validate the file is valid JSON and an array of correctly shaped job objects before pushing","Run 'wmill whoami' to confirm token/workspace validity and permissions","Test the import with a small file (one job) to isolate payload-schema issues"],"exampleFix":"// before: invalid payload shape\n[{\"path\": \"f/foo\"}]  // server 400: missing required fields\n// after: export proper completed-job objects\n[{\"id\": \"...\", \"path\": \"f/foo\", \"args\": {}, \"result\": ..., \"...\": \"...\"}]\n// verify first: cat completed_jobs.json | jq . >/dev/null && wmill jobs push","handlingStrategy":"try-catch","validationCode":"const content = await readTextFile(completedPath);\nconst jobs = JSON.parse(content); // throws early on malformed JSON\nif (!Array.isArray(jobs)) throw new Error(\"Expected array\");\n// sanity: every entry has the fields the import API requires\nfor (const j of jobs) {\n  if (!j.path) throw new Error(\"Each completed job needs at least a 'path'\");\n}","typeGuard":"function isCompletedJob(v: unknown): v is { path: string; [k: string]: unknown } {\n  return typeof v === \"object\" && v !== null && typeof (v as any).path === \"string\";\n}","tryCatchPattern":"try {\n  await wmillJobsPush({ completedFile: path });\n} catch (e) {\n  const msg = String(e);\n  if (msg.includes(\"Failed to push completed jobs\")) {\n    const cause = msg.split(\"Failed to push completed jobs: \")[1];\n    if (cause?.includes(\"Unexpected token\")) console.error(\"Malformed JSON in completed_jobs.json\");\n    else console.error(\"API import failed:\", cause); // check token/workspace/payload\n  }\n}","preventionTips":["Validate JSON and job shape before every push (jq + schema check)","Run 'wmill whoami' to catch token/workspace problems early","Start with a one-job file to isolate payload-schema rejections","Retry pushes in CI with backoff to ride out transient network errors"],"tags":["cli","json","api","jobs"],"backgroundTag":"api-request-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}