vercel/next.js · error
Specified i18n.locales must be an array of locale strings e.
Error message
Specified i18n.locales must be an array of locale strings e.g. ["en-US", "nl-NL"] received ${typeof i18n.locales}.
See more info here: https://nextjs.org/docs/messages/invalid-i18n-config What it means
A redundant defensive re-check at config.ts:1292 that `i18n.locales` is still an array, after the domains-validation block has run. Because the identical `!Array.isArray` check at line 1207 already guards entry into the i18n block and the block never reassigns `locales` before this point, this branch is effectively unreachable in normal flow. The message differs slightly ('must be an array of locale strings').
Source
Thrown at packages/next/src/server/config.ts:1293
}
}
return hasInvalidLocale
})
if (invalidDomainItems.length > 0) {
throw new Error(
`Invalid i18n.domains values:\n${invalidDomainItems
.map((item: any) => JSON.stringify(item))
.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`
)
}View on GitHub (pinned to 0ae8c72462)
Solutions
- Treat this identically to error 200: ensure `i18n.locales` is an array of strings.
- Audit any custom config plugins or `require()`-time mutations of the config object that run during normalization.
Example fix
// before
i18n: { locales: 'en-US', defaultLocale: 'en-US' }
// after
i18n: { locales: ['en-US'], defaultLocale: 'en-US' } Defensive patterns
Strategy: type-guard
Validate before calling
// Same as 200 — this branch is defensively redundant.
if (!Array.isArray(i18n.locales)) throw new Error('locales must be array'); Type guard
const isLocaleArray = (i18n: any): i18n is { locales: string[] } =>
Array.isArray(i18n?.locales); Prevention
- Treat identically to error 200.
- Avoid plugins that mutate `i18n.locales` mid-normalization.
When it happens
Trigger: In standard Next.js loading this is unreachable because line 1207 throws first for a non-array `locales`. It could only fire if a custom plugin or middleware mutated `i18n.locales` to a non-array between the two checks, which the core code does not do.
Common situations: Essentially never seen in practice; if you encounter it, suspect a config plugin or monkey-patch that mutates the `i18n` object during normalization.
Related errors
- Specified i18n.locales should be an Array received ${typeof
- Specified i18n.defaultLocale should be a string. See more in
- Specified i18n.domains must be an array of domain objects e.
- Specified i18n.localeDetection should be undefined or a bool
- Specified "i18n" cannot be used with "output: export". See m
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/1ba0298eb9f5c2ba.
Report an issue: GitHub.