payloadcms/payload · error · Error

Localization is not enabled in payload config

Error message

Localization is not enabled in payload config

What it means

localizeStatus converts a scalar version._status into a per-locale status object, so it requires payload.config.localization to be configured. Thrown when the migration is invoked on a config that has no localization block, since there are no locales to map status onto.

Source

Thrown at packages/db-mongodb/src/predefinedMigrations/migrateLocalizeStatus.ts:93

 * 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)
    if (collection) {
      entityConfig = collection
    }
  } else if (globalSlug) {
    const global = payload.config.globals.find((g) => g.slug === globalSlug)
    if (global) {
      entityConfig = global
    }
  }

  if (!entityConfig) {
    throw new Error(

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Add a localization block to payload.config.ts (localization: { locales: [...], defaultLocale: '...' }) before running the migration.
  2. Remove versions.drafts.localizeStatus from the entity if you do not intend to use per-locale status.
  3. Run via migrateLocalizeStatus() which no-ops gracefully when localization is absent.
  4. Verify config consistency: localizeStatus requires localization at the config root.

Example fix

// before
export default buildConfig({
  collections: [{
    slug: 'posts',
    versions: { drafts: { localizeStatus: true } },
  }],
  // no localization block
})

// after
export default buildConfig({
  localization: {
    locales: [{ code: 'en' }, { code: 'es' }],
    defaultLocale: 'en',
  },
  collections: [{
    slug: 'posts',
    versions: { drafts: { localizeStatus: true } },
  }],
})
Defensive patterns

Strategy: validation

Validate before calling

function assertLocalizationEnabled(config: { localization?: unknown }) {
  if (!config.localization) {
    throw new Error('Enable payload.config.localization before running the localize-status migration')
  }
}

Type guard

function hasLocalization(config: unknown): config is { localization: { locales: unknown[]; defaultLocale: string } } {
  return typeof config === 'object' && config !== null && 'localization' in config && Boolean((config as any).localization)
}

Prevention

When it happens

Trigger: Calling localizeStatus() for a collection/global that has drafts.localizeStatus enabled, but the top-level payload.config.localization is missing or falsy. Note the orchestrator migrateLocalizeStatus short-circuits when localization is absent, so this is mainly reachable via direct localizeStatus calls or an inconsistent config.

Common situations: Enabling versions.drafts.localizeStatus on an entity without enabling localization in payload.config; running the migration against a config where localization was removed after the entity flag was set.

Related errors


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