{"record":{"id":"c3a3c41e54c4922f","repo":"payloadcms/payload","slug":"inline-task-with-id-taskid-does-not-have-a-vali","errorCode":null,"errorMessage":"Inline task with ID ${taskID} does not have a valid handler.","messagePattern":"Inline task with ID (.+?) does not have a valid handler\\.","errorType":"exception","errorClass":"TaskError","httpStatus":null,"severity":"error","filePath":"packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts","lineNumber":114,"sourceCode":"        } else if (typeof finalRetriesConfig?.shouldRestore === 'function') {\n          shouldRestore = await finalRetriesConfig.shouldRestore({\n            input,\n            job,\n            req,\n            taskStatus,\n          })\n        }\n        if (shouldRestore) {\n          return taskStatus.output\n        }\n      }\n\n      const runner = isInline\n        ? (task as TaskHandler<TaskSlug>)\n        : await getTaskHandlerFromConfig(taskConfig)\n\n      if (!runner || typeof runner !== 'function') {\n        throw new TaskError({\n          executedAt,\n          input,\n          job,\n          message: isInline\n            ? `Inline task with ID ${taskID} does not have a valid handler.`\n            : `Task with slug ${taskSlug} in workflow ${job.workflowSlug} does not have a valid handler.`,\n          parent,\n          retriesConfig: finalRetriesConfig,\n          taskConfig,\n          taskID,\n          taskSlug,\n          taskStatus,\n          workflowConfig,\n        })\n      }\n\n      let output: TaskHandlerResult<string>['output']\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts#L96-L132","documentation":"Thrown when an inline task's `task` argument is not a function (or is falsy). The runner assigns `runner = task` for inline tasks, then validates `typeof runner === 'function'`; a non-function inline handler is a programming error in the calling workflow code.","triggerScenarios":"Calling the inline task runner (`req.tasks` / runTask with an inline task) and passing `task` as undefined, an object, or a non-function import — e.g. forgetting to default-export the handler, or passing a config object instead of the function.","commonSituations":"Importing a handler object instead of its function member; passing `task: undefined` because of an optional that was never set; refactor that changed the inline task signature.","solutions":["Pass a function as the `task` argument for inline tasks.","Verify the handler import: `typeof task === 'function'` before queueing.","If you meant a configured task, use the task slug path instead of an inline task."],"exampleFix":"// before\nawait req.tasks('step', { task: MyTaskConfig /* object, not fn */ })\n\n// after\nawait req.tasks('step', { task: myTaskHandler })","handlingStrategy":"type-guard","validationCode":"function isTaskHandler(value: unknown): value is (...args: any[]) => any {\n  return typeof value === 'function'\n}\n\nif (!isTaskHandler(task)) {\n  throw new Error('inline task handler must be a function')\n}\n\nawait req.tasks('step', { task })","typeGuard":"type TaskHandler = (args: any) => Promise<any> | any\n\nfunction isInlineTaskHandler(value: unknown): value is TaskHandler {\n  return typeof value === 'function'\n}\n\nif (!isInlineTaskHandler(task)) {\n  throw new TypeError('Expected a function for inline task')\n}","tryCatchPattern":"try {\n  await req.tasks('step', { task })\n} catch (err) {\n  if (err instanceof TaskError && err.message.includes('does not have a valid handler')) {\n    // replace the inline task arg with a real function\n  } else throw err\n}","preventionTips":["Always pass a function (not a config object) as the inline `task` argument.","Add a unit test asserting `typeof task === 'function'` before queueing.","Use the slug-based task path when you want config-driven tasks."],"tags":["jobs","tasks","inline-task","type-error"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}