{"record":{"id":"008c3a6e26ce7f2d","repo":"payloadcms/payload","slug":"either-collectionslug-or-globalslug-must-be-provid-008c3a","errorCode":null,"errorMessage":"Either collectionSlug or globalSlug must be provided","messagePattern":"Either collectionSlug or globalSlug must be provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/drizzle/src/postgres/predefinedMigrations/localize-status/index.ts","lineNumber":23,"sourceCode":"\nimport { migrateMainCollectionStatus } from './migrateMainCollection.js'\nimport { migrateMainGlobalStatus } from './migrateMainGlobal.js'\n\nexport type LocalizeStatusArgs = {\n  collectionSlug?: string\n  db: any\n  globalSlug?: string\n  payload: Payload\n  req?: any\n  sql: any\n}\n\nexport async function migratePostgresLocalizeStatus(args: LocalizeStatusArgs): Promise<void> {\n  const { collectionSlug, db, globalSlug, payload, req, sql } = args\n  const schemaName = db.schemaName ?? 'public'\n\n  if (!collectionSlug && !globalSlug) {\n    throw new Error('Either collectionSlug or globalSlug must be provided')\n  }\n\n  if (collectionSlug && globalSlug) {\n    throw new Error('Cannot provide both collectionSlug and globalSlug')\n  }\n\n  const entitySlug = collectionSlug || globalSlug\n  // Convert camelCase slugs to snake_case and add version prefix/suffix\n  const versionsTable = collectionSlug\n    ? `_${toSnakeCase(collectionSlug)}_v`\n    : `_${toSnakeCase(globalSlug!)}_v`\n  const localesTable = `${versionsTable}_locales`\n\n  if (!payload.config.localization) {\n    throw new Error('Localization is not enabled in payload config')\n  }\n\n  // Check if versions are enabled on this collection/global","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/postgres/predefinedMigrations/localize-status/index.ts#L5-L41","documentation":"Argument-contract error from the `migratePostgresLocalizeStatus` predefined migration: the function requires exactly one target entity, so `collectionSlug` and `globalSlug` cannot both be omitted. With neither supplied there is nothing to localize, so the migration refuses to guess.","triggerScenarios":"Invoking `migratePostgresLocalizeStatus({ db, payload, sql })` (or the CLI predefined-migration runner wrapping it) without passing `collectionSlug` or `globalSlug`.","commonSituations":"Copy-pasting the migration invocation from docs and forgetting the slug argument; building a generic loop that iterates entities but skips empty cases incorrectly; programmatic invocation with a falsy slug variable.","solutions":["Pass exactly one of `collectionSlug` or `globalSlug` identifying the localized, versions-enabled entity to migrate.","If iterating entities, skip iterations where neither slug applies rather than calling the migration with empty args.","Guard the call site with an `if (collectionSlug || globalSlug)` check."],"exampleFix":"// before\nawait migratePostgresLocalizeStatus({ db, payload, req, sql })\n// after\nawait migratePostgresLocalizeStatus({ collectionSlug: 'posts', db, payload, req, sql })","handlingStrategy":"validation","validationCode":"function runLocalizeStatus(args) {\n  const { collectionSlug, globalSlug } = args\n  if (!collectionSlug && !globalSlug) {\n    throw new Error('Provide collectionSlug or globalSlug')\n  }\n  return migratePostgresLocalizeStatus(args)\n}","typeGuard":"const hasEntitySlug = (a): a is { collectionSlug: string } | { globalSlug: string } =>\n  typeof a?.collectionSlug === 'string' || typeof a?.globalSlug === 'string'","tryCatchPattern":"null","preventionTips":["Wrap predefined migrations in a thin validation layer.","Always pass exactly one slug argument."],"tags":["migrations","localization","argument-validation","predefined-migration"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}