payloadcms/payload · error · Error

Either collectionSlug or globalSlug must be provided

Error message

Either collectionSlug or globalSlug must be provided

What it means

Thrown by migrateSqliteLocalizeStatus when neither collectionSlug nor globalSlug is supplied. The migration operates on one versioned entity at a time, so exactly one target slug is required.

Source

Thrown at packages/drizzle/src/sqlite/predefinedMigrations/localize-status/index.ts:22

import { calculateVersionLocaleStatuses } from 'payload/migrations'
import toSnakeCase from 'to-snake-case'

import { migrateMainCollectionStatus } from './migrateMainCollection.js'
import { migrateMainGlobalStatus } from './migrateMainGlobal.js'

export type LocalizeStatusArgs = {
  collectionSlug?: string
  db: any
  globalSlug?: string
  payload: Payload
  req?: any
}

export async function migrateSqliteLocalizeStatus(args: LocalizeStatusArgs): Promise<void> {
  const { collectionSlug, db, globalSlug, payload, req } = 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
  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

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Pass exactly one of collectionSlug (for a collection) or globalSlug (for a global) to the call.
  2. If scripting over many entities, guard the call site: only invoke when the slug is truthy.

Example fix

// before
await migrateSqliteLocalizeStatus({ db, payload })
// after
await migrateSqliteLocalizeStatus({ db, payload, collectionSlug: 'posts' })
Defensive patterns

Strategy: validation

Validate before calling

function assertOneEntitySlug(args) {
  if (!args.collectionSlug && !args.globalSlug) {
    throw new Error('Pass either collectionSlug or globalSlug')
  }
}

Type guard

const hasEitherSlug = (a) => Boolean(a.collectionSlug) || Boolean(a.globalSlug)

Prevention

When it happens

Trigger: Calling migrateSqliteLocalizeStatus({ db, payload }) with both collectionSlug and globalSlug omitted.

Common situations: Destructuring args incompletely; calling the migration in a loop and passing undefined for the slug variable on some iterations.

Related errors


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