{"record":{"id":"f0744f6ae0ee154b","repo":"windmill-labs/windmill","slug":"errormsg-job-failed","errorCode":null,"errorMessage":"errorMsg ?? 'Job failed'","messagePattern":"errorMsg \\?\\? 'Job failed'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/jobs/utils.ts","lineNumber":112,"sourceCode":"\t\t\tawait new Promise((resolve) =>\n\t\t\t\tsetTimeout(resolve, attempts ? 500 * attempts : pollDelayMs(polls++))\n\t\t\t)\n\t\t\tconst job = await JobService.getCompletedJobResultMaybe({\n\t\t\t\tid: uuid,\n\t\t\t\tworkspace\n\t\t\t})\n\t\t\tif (job.success) {\n\t\t\t\tif (withJobData) {\n\t\t\t\t\treturn { job: { id: uuid }, result: job.result }\n\t\t\t\t} else {\n\t\t\t\t\treturn job.result as any\n\t\t\t\t}\n\t\t\t} else if (job.completed) {\n\t\t\t\tattempts = maxRetries\n\t\t\t\tlet errorMsg: string | undefined = (job?.result as any)?.error?.message\n\t\t\t\tif (typeof errorMsg !== 'string') errorMsg = undefined\n\t\t\t\tconsole.error('JOB FAILED', job.result)\n\t\t\t\tthrow new Error(errorMsg ?? 'Job failed')\n\t\t\t} else if (failIfNoWorkerForTag && Date.now() >= noWorkerProbeAt) {\n\t\t\t\tconst tag = await missingWorkerTagOfQueuedJob(workspace, uuid)\n\t\t\t\tnoWorkerProbeAt = Date.now() + NO_WORKER_PROBE_INTERVAL_MS\n\t\t\t\tunservedProbes = tag ? unservedProbes + 1 : 0\n\t\t\t\tif (tag && unservedProbes >= NO_WORKER_CONFIRMATIONS) {\n\t\t\t\t\tif (!reportedNoWorker) {\n\t\t\t\t\t\treportedNoWorker = true\n\t\t\t\t\t\tonNoWorkerForTag?.(tag)\n\t\t\t\t\t}\n\t\t\t\t\t// Reads give up the wait but leave the job queued: cancelling one would\n\t\t\t\t\t// remove the very backlog the autoscaler scales up on, so a group coming\n\t\t\t\t\t// back from zero (300s cooldown) would never recover. Writes keep\n\t\t\t\t\t// waiting instead (see `sideEffecting`).\n\t\t\t\t\tif (!sideEffecting) throw new NoWorkerForTagError(tag)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tif (e instanceof NoWorkerForTagError) {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/jobs/utils.ts#L94-L130","documentation":"pollJobResult polls a script/job until completion and throws when the finished job's result contains an error, preferring the job's own error.message and falling back to 'Job failed'. It converts an async job failure into a rejected promise for the caller.","triggerScenarios":"A polled job ends with status failure/completed-with-error: run failed (unhandled exception in the script), or the script returned { error: { message } } in its result.","commonSituations":"Script code raised (bad input, missing dependency, timeout); the job was denied/queued into failure by worker errors; API responses where result.error.message is absent so only the generic message appears.","solutions":["Read the thrown message (job result error.message) and fix the script's root cause; full result is logged via console.error('JOB FAILED', ...).","Open the run in the UI run history to see the stack trace and logs.","If the message is the generic 'Job failed', inspect the run logs server-side for the real exception.","Add retry/validation in the script for transient inputs, and handle the rejection at the call site."],"exampleFix":"// before\nawait pollJobResult(ws, uuid)\n// after\ntry { await pollJobResult(ws, uuid) } catch (e) { console.error('run failed:', e.message) }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function jobHasErrorMessage(job) { return typeof (job?.result as any)?.error?.message === 'string' }","tryCatchPattern":"try { const result = await pollJobResult(ws, uuid) } catch (e) { showError(e.message); openRunLogs(uuid) }","preventionTips":["Check run logs in the UI when the message is the generic 'Job failed'","Add input validation inside scripts to fail fast with descriptive messages","Set retries/maxRetries appropriately for transient failures"],"tags":["jobs","async","script-failure"],"backgroundTag":"job-execution-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"}