payloadcms/payload · critical · DuplicateCollection
Collection slug already in use: "${config.collections![i]!.s
Error message
Collection slug already in use: "${config.collections![i]!.slug}" What it means
Thrown at sanitize time when two collections declare the same `slug`. Collection slugs are the primary key for the REST API, the DB table name, and cross-collection references, so duplicates are fatal. The check maintains a `Set` of slugs and raises `DuplicateCollection` on the second occurrence.
Source
Thrown at packages/payload/src/config/sanitize.ts:405
existingFieldNames: new Set(),
fields: sanitizedBlock.fields,
parentIsLocalized: false,
richTextSanitizers,
validRelationships,
})
const flattenedSanitizedBlock = flattenBlock({ block })
config.blocks.push(flattenedSanitizedBlock)
}
}
// Track orderable join fields during sanitization
const orderableJoins: OrderableJoinInfo[] = []
for (let i = 0; i < config.collections!.length; i++) {
if (collectionSlugs.has(config.collections![i]!.slug)) {
throw new DuplicateCollection('slug', config.collections![i]!.slug)
}
collectionSlugs.add(config.collections![i]!.slug)
const draftsConfig = config.collections![i]?.versions?.drafts
if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {
schedulePublishCollections.push(config.collections![i]!.slug)
}
if (config.collections![i]!.enableQueryPresets) {
queryPresetsCollections.push(config.collections![i]!.slug)
if (!validRelationships.includes(queryPresetsCollectionSlug)) {
validRelationships.push(queryPresetsCollectionSlug)
}
}
View on GitHub (pinned to 00c58b35c0)
Solutions
- Rename one of the colliding collections' `slug` to a unique value.
- If a plugin registers the conflicting collection, disable or override it rather than redefining.
- Grep the config tree for the duplicated slug to find both definitions.
Example fix
// before
collections: [
{ slug: 'media', upload: true, fields: [] },
{ slug: 'media', upload: true, fields: [] },
]
// after
collections: [
{ slug: 'media', upload: true, fields: [] },
{ slug: 'documents', upload: true, fields: [] },
] Defensive patterns
Strategy: validation
Validate before calling
const slugs = config.collections.map((c) => c.slug)
const dup = slugs.find((s, i) => slugs.indexOf(s) !== i)
if (dup) {
throw new Error(`Duplicate collection slug: '${dup}'`)
} Type guard
function collectionSlugsUnique(collections: { slug: string }[]): boolean {
const seen = new Set<string>()
for (const c of collections) {
if (seen.has(c.slug)) return false
seen.add(c.slug)
}
return true
} Prevention
- Assert unique slugs in a config unit test before buildConfig.
- Watch for plugins that register collections colliding with yours.
- Use a consistent naming convention to avoid accidental reuse.
When it happens
Trigger: Two collection configs with `{ slug: 'posts' }`; a plugin that registers a collection colliding with one you defined; copy-pasting a collection config and forgetting to rename the slug.
Common situations: Adding a plugin that brings its own `users`/`media` collection while you also define one; refactoring slugs and leaving a stale duplicate; monorepo shared config imported twice.
Related errors
- ${sanitizedConfig.admin!.user} is not a valid admin user col
- `jobs.processingLease.safetyBuffer` must be non-negative and
- Collection with the slug ${globalSlug} was not found
- Collection config for ${join.field.collection.toString()} wa
- ERROR: Failed to retrieve collection with the slug "${collec
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/457cc4fedb34c464.
Report an issue: GitHub.