Skip to content

RangeError: Map maximum size exceeded with createMessagesDeclaration on large message files (~2,500+ keys) #2296

@arolariu

Description

@arolariu

Encountering RangeError: Map maximum size exceeded out of the blue.

Description

I have some large messages files (~218KB, ~2,554 leaf keys, max nesting depth 6) in my project. Whenever I do next build, the build fails due to the typescript server running out of memory for type checking -- I presume that my current setup (with very large, nested messages AND lots of useTranslations() calls) makes the typescript server crash.

Here's the exact crash that it encounteres during type checking:

RangeError: Map maximum size exceeded
    at Map.set (<anonymous>)
    at getStringLiteralType (tsc.js:62989:65)
    at getTemplateLiteralType (tsc.js:61982:14)

The typescript compilation itself succeeds (✓ Compiled successfully in 41s, for example), but the subsequent TypeScript type-check phase hits the V8 Map entry limit (2^24 = 16,777,216 entries).

I've tried to use the --max-old-space-size flag, but it does NOT help as this is an entry count limit, not a memory issue.

Environment

  • next-intl: 4.8.3
  • Next.js: 16.2.1
  • TypeScript: 5.9.3
  • Node.js: 24.x
  • OS: Windows 11 / Ubuntu (GitHub Actions)

Reproduction Steps

  1. Create a Next.js App Router project with next-intl v4
  2. Create a messages/en.json with ~2,500+ leaf keys at max depth 6 (see metrics below)
  3. Have ~170 useTranslations() call sites across the project
  4. Run next build

Expected: Build succeeds with type-checking
Actual: RangeError: Map maximum size exceeded during type-check phase

Message File Metrics

Metric Value
File size 218.5 KB
Total leaf keys 2,554
Total namespaces 851
Max nesting depth 6
Top-level namespaces 14
Locales 3 (en, ro, fr)
useTranslations() call sites ~170

Root Cause Analysis

The generated .d.json.ts creates a type representing all ~2,554 dot-separated key paths as a string literal union. When useTranslations("SomeNamespace") is called, TypeScript's recursiveTypeRelatedTo compares each namespace path against the full union. With ~170 call sites × ~2,554 key paths, the combinatorial type comparisons exceed V8's Map limit of 16,777,216 entries.

This is fundamentally the same issue as:

(^-- above paragraphs have been written by Claude Opus 4.6 1M context)

Current Workaround

Setting typescript.ignoreBuildErrors: true in next.config.ts and relying on separate CI type-checking.

Minimal Reproduction

WIP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions