vercel/next.js · error
Specified i18n.locales contains invalid values (${invalidLoc
Error message
Specified i18n.locales contains invalid values (${invalidLocales.map(String).join(', ')}), locales must be valid locale tags provided as strings e.g. "en-US".
See here for list of valid language sub-tags: http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry What it means
Thrown when every element of `i18n.locales` is a string but one or more are not valid BCP-47-style locale tags as far as Next's string check is concerned. The filter at config.ts:1298 only removes non-string entries; this throw at line 1302 fires for the surviving non-string values, listing them via `String()`. Note: Next does not deeply validate locale tags against the IANA registry — it only rejects non-strings — so the message's IANA link is advisory.
Source
Thrown at packages/next/src/server/config.ts:1303
.join(
'\n'
)}\n\ndomains value must follow format { domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
}
if (!Array.isArray(i18n.locales)) {
throw new Error(
`Specified i18n.locales must be an array of locale strings e.g. ["en-US", "nl-NL"] received ${typeof i18n.locales}.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
const invalidLocales = i18n.locales.filter(
(locale: any) => typeof locale !== 'string'
)
if (invalidLocales.length > 0) {
throw new Error(
`Specified i18n.locales contains invalid values (${invalidLocales
.map(String)
.join(
', '
)}), locales must be valid locale tags provided as strings e.g. "en-US".\n` +
`See here for list of valid language sub-tags: http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry`
)
}
if (!i18n.locales.includes(i18n.defaultLocale)) {
throw new Error(
`Specified i18n.defaultLocale should be included in i18n.locales.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
const normalizedLocales = new Set()
const duplicateLocales = new Set()
View on GitHub (pinned to 0ae8c72462)
Solutions
- Ensure every element of `locales` is a string locale tag.
- If generating locales dynamically, filter to strings first: `locales: allLocales.filter((l) => typeof l === 'string')`.
- Cross-check tags against the IANA language subtag registry for correct formatting (e.g. `en-US`, not `en_US`).
Example fix
// before
i18n: { locales: ['en-US', 42, 'fr-FR'], defaultLocale: 'en-US' }
// after
i18n: { locales: ['en-US', 'fr-FR'], defaultLocale: 'en-US' } Defensive patterns
Strategy: validation
Validate before calling
const invalid = i18n.locales.filter((l: any) => typeof l !== 'string');
if (invalid.length) throw new Error(`non-string locales: ${invalid}`); Type guard
function allStrings(arr: any[]): arr is string[] {
return arr.every((x) => typeof x === 'string');
} Prevention
- Type locales as `string[]`, not `any[]`.
- When building locales dynamically, filter to strings before assigning.
When it happens
Trigger: Placing a number, boolean, object, or null inside `locales`, e.g. `locales: ['en-US', 123]` or `locales: ['en-US', null]`. Pure-garbage strings like `'foo-bar-baz-qux-xyz'` will NOT trigger this (they pass the `typeof === 'string'` filter).
Common situations: Accidentally pushing a non-string into the locales array via dynamic code; spreading a config map that yields mixed types; JSON config with a numeric locale value.
Related errors
- Invalid i18n.domains values: ${invalidDomainItems.map((item:
- Specified i18n.defaultLocale should be included in i18n.loca
- Specified i18n.locales contains the following duplicate loca
- Specified "i18n" cannot be used with "output: export". See m
- Specified basePath has to start with a /, found "${result.ba
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/d656649e93e38eeb.
Report an issue: GitHub.