vercel/next.js · error
Specified i18n should be an object received ${i18nType}. See
Error message
Specified i18n should be an object received ${i18nType}.
See more info here: https://nextjs.org/docs/messages/invalid-i18n-config What it means
When `i18n` is provided it must be an object describing locales, defaultLocale, and domains. The guard at config.ts:1197-1205 runs before any sub-property checks; a truthy non-object value (string, number, array, boolean) is rejected immediately. This protects the subsequent `i18n.locales` / `i18n.defaultLocale` accesses from throwing confusing errors.
Source
Thrown at packages/next/src/server/config.ts:1202
}
}
if (!rootDir) {
throw new Error(
'Failed to find the root directory of the project. This is a bug in Next.js.'
)
}
// 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
View on GitHub (pinned to 0ae8c72462)
Solutions
- Set i18n to a full object: `i18n: { locales: ['en', 'fr'], defaultLocale: 'en' }`.
- If you do not need i18n routing, remove the `i18n` key entirely (i18n routing is also a Pages Router feature and is not used by the App Router).
- Type your config as NextConfig to catch the shape at compile time.
Example fix
// before
module.exports = { i18n: 'en' }
// after
module.exports = { i18n: { locales: ['en', 'fr'], defaultLocale: 'en' } } Defensive patterns
Strategy: type-guard
Validate before calling
if (config.i18n != null && (typeof config.i18n !== 'object' || Array.isArray(config.i18n))) {
throw new Error('i18n must be a plain object');
} Type guard
function isI18nConfig(v: unknown): v is { locales: string[]; defaultLocale: string; domains?: unknown[] } {
if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;
const o = v as any;
return Array.isArray(o.locales) && typeof o.defaultLocale === 'string';
} Prevention
- Type next.config as NextConfig so i18n shape errors surface at compile time.
- Remember i18n is a Pages Router feature; App Router uses routing conventions instead.
When it happens
Trigger: Setting `i18n: 'en'`, `i18n: ['en', 'fr']`, or `i18n: true`. The guard only fires when i18n is truthy and `typeof i18n !== 'object'` (note: arrays are `typeof 'object'` and pass this check, but fail later on `locales`).
Common situations: Confusing i18n with a locales-array shortcut. Misreading docs and supplying just a default locale string. Bad config merge leaving i18n as a primitive.
Related errors
- Specified basePath should not end with /, found "${result.ba
- Specified images should be an object received ${typeof image
- Failed to resolve pattern "${patterns.join(',')}": ${error.m
- Specified pageExtensions is not an array of strings, found "
- Specified pageExtensions is an empty array. Please update it
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/da752c237df90828.
Report an issue: GitHub.