ISSUE: Fix the ‘Maximum Call Stack Size Exceeded’ Error in 5 Minutes

If you’re working with Next.js and MongoDB, there’s a chance you’ve run into this frustrating error:

Maximum call stack size exceeded

Even if your code looks fine, this error can show up and leave you completely confused. I faced this exact issue while working on one of my Next.js projects. I spent hours trying to understand the root cause of the “Maximum call stack size exceeded” error. So I’m writing this article in hopes that it saves someone else from going through the same ordeal.

The background: My Setup

To give some context, I had a server component page (page.tsx) that included three client components:

  1. Map – Renders a map
  2. MapSidebar – Opens a drawer
  3. SearchMap – Input field to search the map
//page.tsx
import { getAssignedOrderCoordinates } from "@/actions/map/getCoordinates";
import Map from "./components/map"
import MapSiderbar from "./components/map-sidebar"
import SearchMap from "./components/search-map"

async function RealtimeLocationPage() {
    //fetched assigned orders lat and lon
    const location = await getAssignedOrderCoordinates();

    return (
        <div className="flex flex-col h-screen relative">
            <div className="flex gap-6 items-center py-6">
                <SearchMap />
                <MapSiderbar orderLocations={location} />
            </div>
            <Map />
        </div>
    )
}

export default RealtimeLocationPage

Here’s where the trouble started: I was using a server action getAssignedOrderCoordinates() to query my MongoDB database. This function returned an array of objects, which I then passed as a prop to the client component MapSidebar.

The moment I did this, I ran into the dreaded error: “Maximum call stack size exceeded”.

But here’s the weird part is — if I stored the array returned by the server action in a variable first, and then passed that variable as a prop, the error (maximum call stack size exceeded) didn’t occur. Something like this:

const data = [
  {
    order_id: 52523,
    city: 'SABAH AL SALEM',
    address: { block: '6', street: '1', house: '38', jaddah: '18' },
    asignee_name: 'Sreenath Kumar',
    asignee: '677677fdf53aced95f98581c',
    coordinates: null
  },
  {
    order_id: 55513,
    city: 'ABU FATIRA',
    address: { block: '11', street: '22', house: '33', jaddah: 'Jaddah' },
    asignee_name: 'test 1',
    asignee: '678926aa67a27f88d7a61516',
    coordinates: null
  },
  {
    order_id: 55518,
    city: 'ABU HALIFA',
    address: { block: '11', street: '22', house: '33', jaddah: 'Jaddah' },
    asignee_name: 'test 1',
    asignee: '678926aa67a27f88d7a61516',
    coordinates: null
  },
  {
    order_id: 55520,
    city: 'ABDULLAH AL SALIM',
    address: { block: '11', street: '22', house: '33', jaddah: 'Jaddah' },
    asignee_name: 'test 1',
    asignee: '678926aa67a27f88d7a61516',
    coordinates: null
  },
  {
    order_id: 55517,
    city: 'ABU AL HASANIYA',
    address: { block: '11', street: '22', house: '33', jaddah: 'Jaddah' },
    asignee_name: 'test 1',
    asignee: '678926aa67a27f88d7a61516',
    coordinates: null
  },
  {
    order_id: 55519,
    city: 'ABU AL HASANIYA',
    address: { block: '11', street: '22', house: '33', jaddah: 'Jaddah' },
    asignee_name: 'test 1',
    asignee: '678926aa67a27f88d7a61516',
    coordinates: null
  }
];

//passing props to the client component
<MapSiderbar orderLocations={data} />

worked fine, while:

const data = await getAssignedOrderCoordinates();
<MapSiderbar orderLocations={data} />

triggered the maximum call stack size exceeded error.

This was confusing, especially since there was no useEffect or obvious loop in the client component.

What does the error actually mean?

After doing some digging, here’s what I found:

The JavaScript engine maintains a call stack to keep track of function calls. Every time a function is invoked, it’s added (pushed) to the stack. Once it finishes, it’s removed (popped). If too many function calls are added without being cleared—like in an infinite loop or deeply nested structure—the stack overflows, resulting in:

“Maximum call stack size exceeded”

Common causes of maximum call stack size exceeded error

Here are some typical reasons this error occurs in React or Next.js:

  1. Recursive Function Calls (Not applicable here)
    Recursive functions are those that call themselves. While recursion is useful in many scenarios (like traversing trees or solving factorials), a missing or incorrect base condition can cause the function to keep calling itself indefinitely. This creates an infinite loop of function calls that keeps stacking up in memory until the JavaScript engine throws a maximum call stack size exceeded
  2. Infinite Rendering Loops
    This is a very common issue in React and Next.js applications. It usually happens when a component’s useEffect, useState, or similar hooks trigger a state update on every render—which causes it to re-render, again and again, endlessly.
  3. Improper Use of Next.js Router
    Using the Next.js useRouter() hook incorrectly inside a useEffect() (without cleanup or guard conditions) can cause the component to re-trigger navigation or state updates on every render. This may lead to navigation loops, which fill the call stack quickly.
  4. Circular Imports
    Circular dependencies happen when two or more files/modules import each other, either directly or indirectly. While JavaScript allows circular imports, they can lead to unpredictable behavior, especially when functions or values are used before they’re fully defined.

    In the context of React or Next.js, circular imports can inadvertently cause:
    1. Components to re-import each other in a loop
    2. Functions to call each other recursively through imported modules
    3. Certain logic to execute multiple times during runtime

    All of this can contribute to a bloated stack and may ultimately trigger the “Maximum call stack size exceeded” error.

I went through every line of my code, looking for these red flags—but nothing stood out.

The Real Culprit: Mongoose

Finally, I took a closer look at my MongoDB query:

const assignedOrders = await Order.find({
  asignee: { $ne: null },
  status: { $ne: 'delivered' }
}).select('order_id city address asignee_name asignee')

Then later in the code:

assignedOrders.map(...)

Here’s what I didn’t realize: Mongoose returns a complex document object, not plain JavaScript objects. These documents contain additional metadata and prototype chains, which can sometimes cause problems when passed directly into React props—especially into client components.

This is why the map() function misbehaved—it wasn’t just iterating over simple objects. It was trying to process everything Mongoose returned, including its internal methods and metadata.

The Fix: Use .lean()

Mongoose provides a simple fix for this: the .lean() method. It tells Mongoose to skip the fancy model instances and return plain JavaScript objects.

Here’s the updated query:

const assignedOrders = await Order.find({
asignee: { $ne: null },
status: { $ne: 'delivered' }
})
.select('order_id city address asignee_name asignee')
.lean()

After adding .lean(), the error (maximum call stack size exceeded) disappeared completely.

Final Thoughts

If you ever face the “Maximum call stack size exceeded” error and can’t trace the cause, check what your database query is returning. If you’re using Mongoose, make sure you’re not passing full model instances into client components—especially when dealing with large datasets.

Also, walk through this quick checklist:

  • Are you calling any recursive function?
  • Is there a state change triggering a re-render loop?
  • Are you using router.push() or similar calls incorrectly?
  • Are there circular imports between modules?
  • Are you passing heavy Mongoose objects into React components?

If you’re stuck—don’t panic. Sometimes the issue isn’t in your logic, it’s in the shape of your data.

Hope this helps you save hours like I wish I had! If you need further any help you can reach to me through this

Support the author to get such amazing content

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *