payloadcms/payload · error · Error
Cannot provide both collectionSlug and globalSlug
Error message
Cannot provide both collectionSlug and globalSlug
What it means
Argument-contract error from `migratePostgresLocalizeStatus`: a single migration targets either a collection or a global, never both. Passing both is ambiguous because the versions-table name and locales table differ per entity type, so the migration refuses to pick.
Source
Thrown at packages/drizzle/src/postgres/predefinedMigrations/localize-status/index.ts:27
export type LocalizeStatusArgs = {
collectionSlug?: string
db: any
globalSlug?: string
payload: Payload
req?: any
sql: any
}
export async function migratePostgresLocalizeStatus(args: LocalizeStatusArgs): Promise<void> {
const { collectionSlug, db, globalSlug, payload, req, sql } = args
const schemaName = db.schemaName ?? 'public'
if (!collectionSlug && !globalSlug) {
throw new Error('Either collectionSlug or globalSlug must be provided')
}
if (collectionSlug && globalSlug) {
throw new Error('Cannot provide both collectionSlug and globalSlug')
}
const entitySlug = collectionSlug || globalSlug
// Convert camelCase slugs to snake_case and add version prefix/suffix
const versionsTable = collectionSlug
? `_${toSnakeCase(collectionSlug)}_v`
: `_${toSnakeCase(globalSlug!)}_v`
const localesTable = `${versionsTable}_locales`
if (!payload.config.localization) {
throw new Error('Localization is not enabled in payload config')
}
// Check if versions are enabled on this collection/global
let entityConfig
if (collectionSlug) {
const collection = payload.config.collections.find((c) => c.slug === collectionSlug)
if (collection) {View on GitHub (pinned to 00c58b35c0)
Solutions
- Supply exactly one slug — `collectionSlug` for a collection or `globalSlug` for a global — and remove the other.
- Branch the call site: `if (collectionSlug) migrate({...collectionSlug}) else if (globalSlug) migrate({...globalSlug})`.
- Add a runtime assert at the caller to fail fast with a clearer message before reaching the migration.
Example fix
// before
await migratePostgresLocalizeStatus({ collectionSlug: 'posts', globalSlug: 'settings', db, payload, sql })
// after
await migratePostgresLocalizeStatus({ collectionSlug: 'posts', db, payload, sql }) Defensive patterns
Strategy: validation
Validate before calling
const { collectionSlug, globalSlug } = args
if (collectionSlug && globalSlug) {
throw new Error('Pass only one of collectionSlug or globalSlug')
}
await migratePostgresLocalizeStatus(args) Type guard
const isExactlyOneSlug = (a): boolean => Boolean(a?.collectionSlug) !== Boolean(a?.globalSlug)
Try / catch
null
Prevention
- Use XOR-style validation when forwarding mutually exclusive options.
- Avoid generic 'spread all options' wrappers for migrations.
When it happens
Trigger: Calling `migratePostgresLocalizeStatus({ collectionSlug: 'posts', globalSlug: 'settings', db, payload, sql })` with both slug arguments set.
Common situations: A generic wrapper that always forwards both fields; refactoring a call site from one entity type to the other without clearing the old argument; configuration objects reused across collection and global loops.
Related errors
- Either collectionSlug or globalSlug must be provided
- Localization is not enabled in payload config
- ${collectionSlug ? 'Collection' : 'Global'} not found: ${col
- Migration aborted: version__status column not found in ${ver
- Either collectionSlug or globalSlug must be provided
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/b86afef5721231fe.
Report an issue: GitHub.