{"record":{"id":"67728b524413e695","repo":"vercel/next.js","slug":"specified-i18n-locales-contains-the-following-dupl","errorCode":null,"errorMessage":"Specified i18n.locales contains the following duplicate locales:\n${[...duplicateLocales].join(', ')}\nEach locale should be listed only once.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config","messagePattern":"Specified i18n\\.locales contains the following duplicate locales:\n(.+?)\nEach locale should be listed only once\\.\nSee more info here: https://nextjs\\.org/docs/messages/invalid-i18n-config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/next/src/server/config.ts","lineNumber":1331,"sourceCode":"    if (!i18n.locales.includes(i18n.defaultLocale)) {\n      throw new Error(\n        `Specified i18n.defaultLocale should be included in i18n.locales.\\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`\n      )\n    }\n\n    const normalizedLocales = new Set()\n    const duplicateLocales = new Set()\n\n    i18n.locales.forEach((locale) => {\n      const localeLower = locale.toLowerCase()\n      if (normalizedLocales.has(localeLower)) {\n        duplicateLocales.add(locale)\n      }\n      normalizedLocales.add(localeLower)\n    })\n\n    if (duplicateLocales.size > 0) {\n      throw new Error(\n        `Specified i18n.locales contains the following duplicate locales:\\n` +\n          `${[...duplicateLocales].join(', ')}\\n` +\n          `Each locale should be listed only once.\\n` +\n          `See more info here: https://nextjs.org/docs/messages/invalid-i18n-config`\n      )\n    }\n\n    // make sure default Locale is at the front\n    i18n.locales = [\n      i18n.defaultLocale,\n      ...i18n.locales.filter((locale) => locale !== i18n.defaultLocale),\n    ]\n\n    const localeDetectionType = typeof i18n.localeDetection\n\n    if (\n      localeDetectionType !== 'boolean' &&\n      localeDetectionType !== 'undefined'","sourceCodeStart":1313,"sourceCodeEnd":1349,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/server/config.ts#L1313-L1349","documentation":"Thrown at config.ts:1330 when `i18n.locales` contains case-insensitive duplicates. The code lowercases each locale and adds it to a `normalizedLocales` set; if a lowercased form is already present, the original-casing value is recorded in `duplicateLocales`. The error lists the duplicates and requires each locale to appear once.","triggerScenarios":"`locales: ['en-US', 'EN-US']`; `locales: ['fr', 'FR', 'Fr']`; `locales: ['pt-BR', 'pt-br']`. Mixed casing is treated as the same locale.","commonSituations":"Merging locale lists from multiple teams/modules without deduplication; CMS-driven locale config that injects variants; copy-paste duplication.","solutions":["Remove the duplicate locale entries so each appears exactly once.","If duplicates arise from case differences, standardize on a single canonical casing.","Dedupe programmatically when building the list: `locales: [...new Set(allLocales.map((l) => l))]` (and normalize case first if needed)."],"exampleFix":"// before\ni18n: { locales: ['en-US', 'EN-US', 'fr'], defaultLocale: 'en-US' }\n// after\ni18n: { locales: ['en-US', 'fr'], defaultLocale: 'en-US' }","handlingStrategy":"validation","validationCode":"const lower = i18n.locales.map((l: string) => l.toLowerCase());\nif (new Set(lower).size !== lower.length) throw new Error('duplicate (case-insensitive) locales');","typeGuard":"function noCaseInsensitiveDuplicates(locales: string[]): boolean {\n  const lower = locales.map((l) => l.toLowerCase());\n  return new Set(lower).size === lower.length;\n}","tryCatchPattern":null,"preventionTips":["Normalize locale casing upstream (e.g. always canonical case).","Dedupe with `Array.from(new Set(locales.map((l) => l)))` before exporting."],"tags":["config","i18n","validation","deduplication"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}