payloadcms/payload · critical · Error
Task slug "${task.slug}" is already used by a workflow. No t
Error message
Task slug "${task.slug}" is already used by a workflow. No tasks are allowed to have the same slug as a workflow. What it means
Thrown while building the jobs queue config collection when a task's slug collides with an existing workflow slug. Payload disallows the collision because task and workflow slugs share the same namespace on the jobs collection (taskSlugs seeds with 'inline'), so a duplicate would make job routing ambiguous.
Source
Thrown at packages/payload/src/queues/config/collection.ts:27
export const jobsCollectionSlug = 'payload-jobs'
export const getDefaultJobsCollection: (jobsConfig: SanitizedConfig['jobs']) => CollectionConfig = (
jobsConfig,
) => {
const workflowSlugs: Set<string> = new Set()
const taskSlugs: Set<string> = new Set(['inline'])
if (jobsConfig.workflows?.length) {
jobsConfig.workflows.forEach((workflow) => {
workflowSlugs.add(workflow.slug)
})
}
if (jobsConfig.tasks?.length) {
jobsConfig.tasks.forEach((task) => {
if (workflowSlugs.has(task.slug)) {
throw new Error(
`Task slug "${task.slug}" is already used by a workflow. No tasks are allowed to have the same slug as a workflow.`,
)
}
taskSlugs.add(task.slug)
})
}
const logFields: Field[] = [
{
name: 'executedAt',
type: 'date',
required: true,
},
{
name: 'completedAt',
type: 'date',
required: true,View on GitHub (pinned to 00c58b35c0)
Solutions
- Rename the task slug so it is unique across both tasks and workflows.
- Audit `payload.config.ts` jobs.workflows and jobs.tasks for duplicate slugs before starting the server.
- Add a unit test that builds the config and asserts no slug overlap.
Example fix
// before
jobs: {
workflows: [{ slug: 'sync', tasks: [] }],
tasks: [{ slug: 'sync', handler: async () => {} }],
}
// after
jobs: {
workflows: [{ slug: 'sync', tasks: [] }],
tasks: [{ slug: 'sync-task', handler: async () => {} }],
} Defensive patterns
Strategy: validation
Validate before calling
import config from './payload.config'
function assertNoSlugCollision(cfg): void {
const workflows = new Set((cfg.jobs?.workflows ?? []).map((w) => w.slug))
for (const t of cfg.jobs?.tasks ?? []) {
if (workflows.has(t.slug)) {
throw new Error(`Task slug "${t.slug}" collides with a workflow slug`)
}
}
}
assertNoSlugCollision(config) Type guard
function isUniqueAcross<T extends { slug: string }>(
a: T[],
b: T[],
): boolean {
const set = new Set(a.map((x) => x.slug))
return b.every((x) => !set.has(x.slug))
}
if (!isUniqueCross(tasks, workflows)) {
throw new Error('task/workflow slug collision')
} Prevention
- Add a config-build unit test that asserts no task slug equals a workflow slug.
- Keep a single source of truth (constants) for job slugs to avoid drift.
- Review slug changes in PRs that touch jobs config.
When it happens
Trigger: Defining `jobs.tasks` and `jobs.workflows` in buildConfig where a task and a workflow share the same `slug`. The error fires at config build time, before the server starts.
Common situations: Refactoring a workflow into a standalone task and forgetting to rename; copy-paste of a workflow config into tasks; renaming a workflow but leaving an old task with the same name.
Related errors
- Error: the payload config is required to initialize payload.
- Error: missing secret key. A secret key is needed to secure
- Error: the payload config is required for getPayload to work
- You are not allowed to perform this action.
- You are not allowed to perform this action.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/a44fbb0cf852c93e.
Report an issue: GitHub.