{"record":{"id":"b86afef5721231fe","repo":"payloadcms/payload","slug":"cannot-provide-both-collectionslug-and-globalslug-b86afe","errorCode":null,"errorMessage":"Cannot provide both collectionSlug and globalSlug","messagePattern":"Cannot provide both collectionSlug and globalSlug","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/drizzle/src/postgres/predefinedMigrations/localize-status/index.ts","lineNumber":27,"sourceCode":"export 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\n  let entityConfig\n  if (collectionSlug) {\n    const collection = payload.config.collections.find((c) => c.slug === collectionSlug)\n    if (collection) {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/postgres/predefinedMigrations/localize-status/index.ts#L9-L45","documentation":"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.","triggerScenarios":"Calling `migratePostgresLocalizeStatus({ collectionSlug: 'posts', globalSlug: 'settings', db, payload, sql })` with both slug arguments set.","commonSituations":"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.","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."],"exampleFix":"// before\nawait migratePostgresLocalizeStatus({ collectionSlug: 'posts', globalSlug: 'settings', db, payload, sql })\n// after\nawait migratePostgresLocalizeStatus({ collectionSlug: 'posts', db, payload, sql })","handlingStrategy":"validation","validationCode":"const { collectionSlug, globalSlug } = args\nif (collectionSlug && globalSlug) {\n  throw new Error('Pass only one of collectionSlug or globalSlug')\n}\nawait migratePostgresLocalizeStatus(args)","typeGuard":"const isExactlyOneSlug = (a): boolean =>\n  Boolean(a?.collectionSlug) !== Boolean(a?.globalSlug)","tryCatchPattern":"null","preventionTips":["Use XOR-style validation when forwarding mutually exclusive options.","Avoid generic 'spread all options' wrappers for migrations."],"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"}