{"record":{"id":"ba158657a028e704","repo":"payloadcms/payload","slug":"task-handler-threw-an-error","errorCode":null,"errorMessage":"Task handler threw an error","messagePattern":"Task handler threw an error","errorType":"exception","errorClass":"TaskError","httpStatus":null,"severity":"error","filePath":"packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts","lineNumber":154,"sourceCode":"            inlineTask: getRunTaskFunction(job, workflowConfig, req, true, updateJob, {\n              taskID,\n              taskSlug,\n            }),\n            input,\n            job: job as unknown as Job<WorkflowSlug>,\n            req,\n            tasks: getRunTaskFunction(job, workflowConfig, req, false, updateJob, {\n              taskID,\n              taskSlug,\n            }),\n          })\n        )?.output\n      } catch (err: any) {\n        if (err instanceof JobCancelledError || err instanceof JobRunAbortedError) {\n          // Job run aborts are handled by the top-level runner.\n          throw err\n        }\n        throw new TaskError({\n          executedAt,\n          input: input!,\n          job,\n          message: err.message || 'Task handler threw an error',\n          output,\n          parent,\n          retriesConfig: finalRetriesConfig,\n          taskConfig,\n          taskID,\n          taskSlug,\n          taskStatus,\n          workflowConfig,\n        })\n      }\n\n      if (taskConfig?.onSuccess) {\n        await taskConfig.onSuccess({\n          input,","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts#L136-L172","documentation":"Thrown as a wrapped `TaskError` when the task handler function throws during execution. The runner catches any non-cancellation error (`JobCancelledError`/`JobRunAbortedError` are rethrown) and re-emits it as a TaskError carrying the original `err.message`, plus task/job context, input, and the resolved retries config. This is the user-facing surface of a handler bug.","triggerScenarios":"The task handler threw — null deref, failed DB write, rejected fetch, business-logic exception, etc. The error propagates with the handler's message (or 'Task handler threw an error' if the thrown value had no message).","commonSituations":"Handler calls an external API that returned an error; null/undefined input access; a DB constraint violation inside the task; downstream service outage.","solutions":["Inspect the TaskError's `message` and `output` (often the original error) to find the root cause.","Fix the handler's failure mode; add input validation and defensive checks.","Configure task `retries` so transient handler failures are retried instead of failing the job."],"exampleFix":"// before\nhandler: async ({ input }) => {\n  return JSON.parse(input.body) // throws on bad input\n}\n\n// after\nhandler: async ({ input }) => {\n  try {\n    return JSON.parse(input.body)\n  } catch {\n    throw new Error(`Invalid JSON in task input: ${input.body}`)\n  }\n}","handlingStrategy":"try-catch","validationCode":"// make handlers defensive and validate inputs\nhandler: async ({ input }) => {\n  if (!input || typeof input.body !== 'string') {\n    throw new Error('Task input.body is required and must be a string')\n  }\n  return JSON.parse(input.body)\n}","typeGuard":"function isTaskError(err: unknown): err is { message: string; taskSlug?: string } {\n  return err instanceof Error && 'taskConfig' in (err as object)\n}","tryCatchPattern":"try {\n  await runJobs({ req })\n} catch (err) {\n  if (isTaskError(err)) {\n    // inspect err.message + err.output; fix handler or bump task.retries\n    logger.error({ task: err.taskSlug, msg: err.message })\n  }\n  throw err\n}","preventionTips":["Validate task inputs at the top of the handler before touching fields.","Configure task.retries so transient failures retry instead of failing the job.","Log handler errors with structured context for debugging."],"tags":["jobs","tasks","handler","runtime-error"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}