payloadcms/payload · error · Error
Either collectionSlug or globalSlug must be provided
Error message
Either collectionSlug or globalSlug must be provided
What it means
The localizeStatus migration helper requires exactly one entity identifier. Thrown when neither collectionSlug nor globalSlug is passed in LocalizeStatusArgs. This is a programmer-argument guard, not a runtime data condition.
Source
Thrown at packages/db-mongodb/src/predefinedMigrations/migrateLocalizeStatus.ts:81
}
for (const global of globals) {
await localizeStatus({ globalSlug: global.slug, payload, req, session })
await cleanupSnapshotDocuments({ connection, entitySlug: global.slug, payload, session })
}
payload.logger.info({ msg: 'localize-status migration completed successfully' })
}
/**
* Converts version._status (and the main document _status) from a scalar string to a
* per-locale object for a single collection or global.
*/
export async function localizeStatus(args: LocalizeStatusArgs): Promise<void> {
const { collectionSlug, globalSlug, payload, req, session } = args
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
// MongoDB collection names are case-insensitive and stored as lowercase
const versionsCollection = `_${entitySlug}_versions`.toLowerCase()
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)View on GitHub (pinned to 00c58b35c0)
Solutions
- Pass exactly one of collectionSlug or globalSlug when calling localizeStatus.
- Prefer the higher-level migrateLocalizeStatus() orchestrator which derives slugs from config automatically.
- Add a unit test asserting your caller always provides a slug.
- Type the caller so omitting both is a compile error (LocalizeStatusArgs already does this weakly).
Example fix
// before
await localizeStatus({ payload, req })
// after
await localizeStatus({ collectionSlug: 'posts', payload, req }) Defensive patterns
Strategy: validation
Validate before calling
function assertLocalizeTarget(args: { collectionSlug?: string; globalSlug?: string }) {
if (!args.collectionSlug && !args.globalSlug) {
throw new Error('localizeStatus requires collectionSlug or globalSlug')
}
} Type guard
type LocalizeArgs = { collectionSlug?: string; globalSlug?: string }
function hasOneEntity(a: LocalizeArgs): a is { collectionSlug: string } | { globalSlug: string } {
return Boolean(a.collectionSlug) !== Boolean(a.globalSlug)
} Prevention
- Always pass exactly one slug to localizeStatus.
- Prefer the migrateLocalizeStatus() orchestrator which derives slugs from config.
- Unit-test custom migration callers to guarantee a slug is present.
When it happens
Trigger: Calling localizeStatus() directly (outside the orchestrator migrateLocalizeStatus) with an args object where both collectionSlug and globalSlug are undefined.
Common situations: A custom migration or script that invokes localizeStatus without an entity slug; refactoring that dropped the slug argument.
Related errors
- Cannot provide both collectionSlug and globalSlug
- ${collectionSlug ? 'Collection' : 'Global'} not found: ${col
- Localization is not enabled in payload config
- Migration aborted: version._status field not found or has un
- Either collection or globalSlug must be passed.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/78a489bec6731188.
Report an issue: GitHub.