nextjs - ✅(Solved) Fix RangeError: Maximum call stack size exceeded when providing next with a config object parsed by node-config [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#90798Fetched 2026-04-08 00:19:32
View on GitHub
Comments
2
Participants
2
Timeline
5
Reactions
0
Timeline (top)
commented ×2cross-referenced ×1issue_type_added ×1referenced ×1

Error Message

npx --no-install next info /[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424 function cloneObject(obj) { ^

RangeError: Maximum call stack size exceeded at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424:21) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27) at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)

Node.js v20.19.4

[next info fails with the bug too!] [Rerunning this again with the buggy line commented out]

Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 24.6.0: Mon Jan 19 22:01:41 PST 2026; root:xnu-11417.140.69.708.3~1/RELEASE_ARM64_T8132 Available memory (MB): 24576 Available CPU cores: 10 Binaries: Node: 20.19.4 npm: 10.8.2 Yarn: 1.22.22 pnpm: N/A Relevant Packages: next: 16.2.0-canary.72 // Latest available version is detected (16.2.0-canary.72). eslint-config-next: N/A react: 19.2.4 react-dom: 19.2.4 typescript: 5.9.3 Next.js Config: output: N/A

Fix Action

Fix / Workaround

We'd like to keep using node-config if possible and obviously would like to be on the latest available version of next 15.x.x for bugfixes. I'm able to step around this issue by adding a patch file to revert cloneObject to its prior version but I don't fully understand why this function was changed / what the consequences of undoing that change would be.

PR fix notes

PR #90812: fix(config): guard cloneObject against circular references

Description (problem / solution / changelog)

Problem

When a Next.js config object is produced by libraries like node-config, the resulting plain objects can contain circular back-references. The current cloneObject function in packages/next/src/server/config.ts has no cycle detection, so it recurses infinitely and crashes:

RangeError: Maximum call stack size exceeded
    at cloneObject (.../next/dist/server/config.js:1424:21)
    at cloneObject (.../next/dist/server/config.js:1459:27)
    ...

Repro: https://github.com/shaver-bigwx/next-node-config-bug-demo

Fixes #90798

Fix

Add a WeakSet (seen) that is passed through all recursive calls. When an object that has already been visited is encountered again, return the original reference to break the cycle instead of recursing.

-function cloneObject(obj: any): any {
+function cloneObject(obj: any, seen: WeakSet<object> = new WeakSet()): any {
   ...
+  // Circular reference guard → return the original reference to break the cycle
+  if (seen.has(obj)) {
+    return obj
+  }
+  seen.add(obj)
   ...
-    return obj.map(cloneObject)
+    return obj.map((item) => cloneObject(item, seen))
   ...
-      result[key] = cloneObject(obj[key])
+      result[key] = cloneObject(obj[key], seen)

Testing

The fix is minimal and surgical — it only affects the recursive clone path for objects that were already visited (circular references). Non-circular objects follow the exact same code path as before.

Changed files

  • packages/next/src/server/config.ts (modified, +19/-7)
  • test/e2e/config-circular-reference/index.test.ts (added, +46/-0)
  • test/unit/clone-object.test.ts (added, +91/-0)

Code Example

npx --no-install next info
/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424
function cloneObject(obj) {
                    ^

RangeError: Maximum call stack size exceeded
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424:21)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)

Node.js v20.19.4

[next info fails with the bug too!]
[Rerunning this again with the buggy line commented out]

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Jan 19 22:01:41 PST 2026; root:xnu-11417.140.69.708.3~1/RELEASE_ARM64_T8132
  Available memory (MB): 24576
  Available CPU cores: 10
Binaries:
  Node: 20.19.4
  npm: 10.8.2
  Yarn: 1.22.22
  pnpm: N/A
Relevant Packages:
  next: 16.2.0-canary.72 // Latest available version is detected (16.2.0-canary.72).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/shaver-bigwx/next-node-config-bug-demo

To Reproduce

  1. npm install
  2. npm run build

Current vs. Expected behavior

Expected: next should be able to start

Actual: next fails to build / fails to start with a RangeError: Maximum call stack size exceeded in the output.

Provide environment information

npx --no-install next info
/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424
function cloneObject(obj) {
                    ^

RangeError: Maximum call stack size exceeded
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1424:21)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)
    at cloneObject (/[redacted]/next-bug-demo/node_modules/next/dist/server/config.js:1459:27)

Node.js v20.19.4

[next info fails with the bug too!]
[Rerunning this again with the buggy line commented out]

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Jan 19 22:01:41 PST 2026; root:xnu-11417.140.69.708.3~1/RELEASE_ARM64_T8132
  Available memory (MB): 24576
  Available CPU cores: 10
Binaries:
  Node: 20.19.4
  npm: 10.8.2
  Yarn: 1.22.22
  pnpm: N/A
Relevant Packages:
  next: 16.2.0-canary.72 // Latest available version is detected (16.2.0-canary.72).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local)

Additional context

Hello,

We've experienced this failure to start upgrading next to any version >15.5.x. We're on the pages router, but I am unsure if that's relevant. We use node-config to parse our config files per deployment environment and feed the parsed config object into next.config.js.

On next >15.5.x, npm run start fails with a stack overflow error. Please see the attached demo repo - npm run build / npm run start fail until the parsed config from node-config is commented out in next.config.js.

I have done some digging and I believe this is due to an interaction between node-config and next, after this commit changed how cloneObject works. Before this change it looks like cloneObject would just enumerate all normal properties of the config object but afterwards it tries to enumerate accessors as well.

What I think is happening is node-config adds extra accessors to our config object when it parses it. Somewhere in the accessors added there is a cyclic reference. The new implementation of cloneObject gets stuck walking the tree infinitely and causes a stack overflow.

We'd like to keep using node-config if possible and obviously would like to be on the latest available version of next 15.x.x for bugfixes. I'm able to step around this issue by adding a patch file to revert cloneObject to its prior version but I don't fully understand why this function was changed / what the consequences of undoing that change would be.

Any help working towards a suitable fix would be greatly appreciated. Cheers!

extent analysis

Quick Fix

Convert the node-config object to a plain JSON‑compatible object before handing it to Next.js.
The circular getters that node-config adds cause next/dist/server/config.cloneObject to recurse forever. Serialising the config (or using config.util.toObject()) strips those accessors and breaks the cycle.


Step‑by‑Step Fix Plan

  1. Install the latest node-config (if you aren’t already).

    npm i config@latest
  2. Update next.config.js. Replace the direct require('config') export with a plain‑object version.

    // next.config.js
    const rawConfig = require('config');               // <-- node‑config object
    // Option A – use the built‑in helper (recommended)
    const plainConfig = rawConfig.util.toObject();     // strips getters & circular refs
    
    // Option B – safe JSON round‑trip (works even if util helper is missing

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING