payloadcms/payload · error · Error
Error importing job queue handler module for path ${path}. T
Error message
Error importing job queue handler module for path ${path}. This is an advanced feature that may require a sophisticated build pipeline, especially when using it in production or within Next.js, e.g. by calling opening the /api/payload-jobs/run endpoint. You will have to transpile the handler files separately and ensure they are available in the same location when the job is run. If you're using an endpoint to execute your jobs, it's recommended to define your handlers as functions directly in your Payload Config, or use import paths handlers outside of Next.js. Import Error:
${e instanceof Error ? e.message : 'Unknown error'} What it means
Thrown by `importHandlerPath` when the dynamic import of a task/workflow handler module (referenced by `handler.path`, split on `#` for named export) fails. The path-based handler is an advanced feature: the module must be importable at runtime, which bundlers (especially Next.js production builds) often break by not emitting/transpiling those files. The message includes the underlying import error for diagnosis.
Source
Thrown at packages/payload/src/queues/operations/runJobs/runJob/importHandlerPath.ts:16
import type { TaskConfig, TaskHandler, TaskSlug } from '../../../config/types/taskTypes.js'
import { dynamicImport } from '../../../../utilities/dynamicImport.js'
/**
* Imports a handler function from a given path.
*/
export async function importHandlerPath<T>(path: string): Promise<T> {
let runner!: T
const [runnerPath, runnerImportName] = path.split('#')
let runnerModule: Record<string, unknown>
try {
runnerModule = await dynamicImport<Record<string, unknown>>(runnerPath!)
} catch (e) {
throw new Error(
`Error importing job queue handler module for path ${path}. This is an advanced feature that may require a sophisticated build pipeline, especially when using it in production or within Next.js, e.g. by calling opening the /api/payload-jobs/run endpoint. You will have to transpile the handler files separately and ensure they are available in the same location when the job is run. If you're using an endpoint to execute your jobs, it's recommended to define your handlers as functions directly in your Payload Config, or use import paths handlers outside of Next.js. Import Error: \n${e instanceof Error ? e.message : 'Unknown error'}`,
)
}
// If the path has indicated an #exportName, try to get it
if (runnerImportName && runnerModule[runnerImportName]) {
runner = runnerModule[runnerImportName] as T
}
// If there is a default export, use it
if (!runner && runnerModule.default) {
runner = runnerModule.default as T
}
// Finally, use whatever was imported
if (!runner) {
runner = runnerModule as T
}View on GitHub (pinned to 00c58b35c0)
Solutions
- Prefer defining handlers as functions directly in the Payload config instead of `handler.path`.
- If you must use a path, transpile/emit the handler file separately and confirm it exists in the build output.
- Run the import path outside Next.js (e.g. a standalone worker) where the file is on disk.
Example fix
// before
handler: { path: './tasks/sync.js#run' }
// after
import { run as syncRun } from './tasks/sync.js'
handler: syncRun Defensive patterns
Strategy: fallback
Validate before calling
// prefer function handlers in config so dynamic import is unnecessary
import { run as syncRun } from './tasks/sync.js'
tasks: [{ slug: 'sync', handler: syncRun }] Type guard
function isHandlerFunction(value: unknown): value is (...args: any[]) => any {
return typeof value === 'function'
}
if (!isHandlerFunction(handler)) {
throw new Error('handler.path is not recommended in bundled builds; use a function handler')
} Try / catch
try {
await runJobs({ req })
} catch (err) {
if (err instanceof Error && err.message.includes('Error importing job queue handler module')) {
// switch the task to a function handler, or ensure the module is emitted in the build
} else throw err
} Prevention
- Avoid handler.path in Next.js/bundled deployments; define handlers as functions.
- If path-based, emit/transpile handler files separately and confirm they exist post-build.
- Run the worker outside Next.js where the path is resolvable on disk.
When it happens
Trigger: A task/workflow uses `handler: { path: './tasks/foo.js#run' }` and the dynamic import of `./tasks/foo.js` throws — file missing in the build output, wrong extension, ESM/CJS mismatch, or the module is outside the bundle.
Common situations: Deploying to Next.js/Vercel where the handler file isn't included in the server bundle; moving handler files without updating paths; using a path that resolves in dev but not in a transpiled prod build.
Related errors
- Task with slug ${taskSlug} in workflow ${job.workflowSlug} d
- Task handler threw an error
- Task ${taskSlug} not found in workflow ${job.workflowSlug}
- Inline task with ID ${taskID} does not have a valid handler.
- Could not find ExportDefaultDeclaration in next.config.js
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/744d94b72979c8c9.
Report an issue: GitHub.