vercel/next.js · error
Specified i18n.locales should be an Array received ${typeof
Error message
Specified i18n.locales should be an Array received ${typeof i18n.locales}.
See more info here: https://nextjs.org/docs/messages/invalid-i18n-config What it means
Thrown during Next.js config normalization when an `i18n` object is present but its `locales` field is not an Array. The validator (`Array.isArray`) runs early in the i18n block, before any locale-content checks, so a wrong-typed `locales` value aborts loading immediately. The error links to the invalid-i18n-config docs page.
Source
Thrown at packages/next/src/server/config.ts:1208
}
// Ensure both properties are set to the same value
result.outputFileTracingRoot = rootDir
dset(result, ['turbopack', 'root'], rootDir)
setHttpClientAndAgentOptions(result || defaultConfig)
if (result.i18n) {
const { i18n } = result
const i18nType = typeof i18n
if (i18nType !== 'object') {
throw new Error(
`Specified i18n should be an object received ${i18nType}.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
if (!Array.isArray(i18n.locales)) {
throw new Error(
`Specified i18n.locales should be an Array received ${typeof i18n.locales}.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
if (i18n.locales.length > 100 && !silent) {
Log.warn(
`Received ${i18n.locales.length} i18n.locales items which exceeds the recommended max of 100.\nSee more info here: https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation`
)
}
const defaultLocaleType = typeof i18n.defaultLocale
if (!i18n.defaultLocale || defaultLocaleType !== 'string') {
throw new Error(
`Specified i18n.defaultLocale should be a string.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
View on GitHub (pinned to 0ae8c72462)
Solutions
- Set `i18n.locales` to an array of locale strings, e.g. `locales: ['en-US', 'nl-NL']`.
- If you have a single locale, still wrap it in an array: `locales: ['en-US']`.
- Check for accidental mutation/merging of the config object that replaces the array with a scalar before Next reads it.
- Remove the entire `i18n` key if you are not using the Pages Router i18n routing (App Router does not use it).
Example fix
// before
module.exports = { i18n: { locales: 'en-US', defaultLocale: 'en-US' } }
// after
module.exports = { i18n: { locales: ['en-US'], defaultLocale: 'en-US' } } Defensive patterns
Strategy: type-guard
Validate before calling
// Before exporting config, assert the shape
const i18n = { locales: ['en-US'], defaultLocale: 'en-US' };
if (!Array.isArray(i18n.locales)) {
throw new Error('i18n.locales must be an array');
}
module.exports = { i18n }; Type guard
function isValidI18n(i18n: unknown): i18n is { locales: unknown[]; defaultLocale: string } {
return (
typeof i18n === 'object' && i18n !== null &&
Array.isArray((i18n as any).locales) &&
typeof (i18n as any).defaultLocale === 'string'
);
} Prevention
- Use the official NextConfig TypeScript type so the compiler rejects non-array locales.
- Validate dynamic/env-driven config with a type guard before exporting.
- Keep locale lists in a single typed constant and reference it from the config.
When it happens
Trigger: Setting `i18n: { locales: 'en-US' }` (a string), `i18n: { locales: { en: 'en-US' } }` (an object), `i18n: { locales: 42 }` (a number), or omitting the property entirely while still passing an `i18n` object triggers the `!Array.isArray(i18n.locales)` check at config.ts:1207.
Common situations: Developers migrating from a per-page i18n setup who write a single locale string instead of an array; copy-pasting locale config from a non-Next source; destructuring or spreading config that drops the array; TypeScript types being bypassed via `as any`.
Related errors
- Specified i18n.defaultLocale should be a string. See more in
- Specified i18n.domains must be an array of domain objects e.
- Specified i18n.locales must be an array of locale strings 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/bf85ed7bdcd70524.
Report an issue: GitHub.