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

  1. Rename one of the colliding collections' `slug` to a unique value.
  2. If a plugin registers the conflicting collection, disable or override it rather than redefining.
  3. 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

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


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/457cc4fedb34c464. Report an issue: GitHub.