Maximum call stack size exceeded error

JavascriptHtmlWebkitCallstackDwr

Javascript Problem Overview


I am using a Direct Web Remoting (DWR) JavaScript library file and am getting an error only in Safari (desktop and iPad)

It says

> Maximum call stack size exceeded.

What exactly does this error mean and does it stop processing completely?

Also any fix for Safari browser (Actually on the iPad Safari, it says

> JS:execution exceeded timeout

which I am assuming is the same call stack issue)

Javascript Solutions


Solution 1 - Javascript

It means that somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit.

This is almost always because of a recursive function with a base case that isn't being met.

Viewing the stack

Consider this code...

(function a() {
    a();
})();

Here is the stack after a handful of calls...

Web Inspector

As you can see, the call stack grows until it hits a limit: the browser hardcoded stack size or memory exhaustion.

In order to fix it, ensure that your recursive function has a base case which is able to be met...

(function a(x) {
    // The following condition 
    // is the base case.
    if ( ! x) {
        return;
    }
    a(--x);
})(10);

Solution 2 - Javascript

You can sometimes get this if you accidentally import/embed the same JavaScript file twice, worth checking in your resources tab of the inspector.

Solution 3 - Javascript

In my case, I was sending input elements instead of their values:

$.post( '',{ registerName: $('#registerName') } )

Instead of:

$.post( '',{ registerName: $('#registerName').val() } )

This froze my Chrome tab to a point it didn't even show me the 'Wait/Kill' dialog for when the page became unresponsive...

Solution 4 - Javascript

There is a recursive loop somewhere in your code (i.e. a function that eventually calls itself again and again until the stack is full).

Other browsers either have bigger stacks (so you get a timeout instead) or they swallow the error for some reason (maybe a badly placed try-catch).

Use the debugger to check the call stack when the error happens.

Solution 5 - Javascript

The problem with detecting stackoverflows is sometimes the stack trace will unwind and you won't be able to see what's actually going on.

I've found some of Chrome's newer debugging tools useful for this.

Hit the Performance tab, make sure Javascript samples are enabled and you'll get something like this.

It's pretty obvious where the overflow is here! If you click on extendObject you'll be able to actually see the exact line number in the code.

enter image description here

You can also see timings which may or may not be helpful or a red herring.

enter image description here


Another useful trick if you can't actually find the problem is to put lots of console.log statements where you think the problem is. The previous step above can help you with this.

In Chrome if you repeatedly output identical data it will display it like this showing where the problem is more clearly. In this instance the stack hit 7152 frames before it finally crashed:

enter image description here

Solution 6 - Javascript

In my case, I was converting a large byte array into a string using the following:

String.fromCharCode.apply(null, new Uint16Array(bytes))

bytes contained several million entries, which is too big to fit on the stack.

Solution 7 - Javascript

In my case, click event was propagating on child element. So, I had to put the following:

> e.stopPropagation()

on click event:

 $(document).on("click", ".remove-discount-button", function (e) {
           e.stopPropagation();
           //some code
        });
 $(document).on("click", ".current-code", function () {
     $('.remove-discount-button').trigger("click");
 });

Here is the html code:

 <div class="current-code">                                      
      <input type="submit" name="removediscountcouponcode" value="
title="Remove" class="remove-discount-button">
   </div>

Solution 8 - Javascript

This can also cause a Maximum call stack size exceeded error:

var items = [];
[].push.apply(items, new Array(1000000)); //Bad

Same here:

items.push(...new Array(1000000)); //Bad

From the Mozilla Docs:

> But beware: in using apply this way, you run the risk of exceeding the > JavaScript engine's argument length limit. The consequences of > applying a function with too many arguments (think more than tens of > thousands of arguments) vary across engines (JavaScriptCore has > hard-coded argument limit of 65536), because the limit (indeed even > the nature of any excessively-large-stack behavior) is unspecified. > Some engines will throw an exception. More perniciously, others will > arbitrarily limit the number of arguments actually passed to the > applied function. To illustrate this latter case: if such an engine > had a limit of four arguments (actual limits are of course > significantly higher), it would be as if the arguments 5, 6, 2, 3 had > been passed to apply in the examples above, rather than the full > array.

So try:

var items = [];
var newItems = new Array(1000000);
for(var i = 0; i < newItems.length; i++){
  items.push(newItems[i]);
}

Solution 9 - Javascript

Check the error details in the Chrome dev toolbar console, this will give you the functions in the call stack, and guide you towards the recursion that's causing the error.

Solution 10 - Javascript

If you need a infinite process/recursion running for some reason, you can use a webworker in a seperate thread. http://www.html5rocks.com/en/tutorials/workers/basics/

if you want to manipulate dom elements and redraw, use animation http://creativejs.com/resources/requestanimationframe/

Solution 11 - Javascript

We recently added a field to an admin site we are working on - contact_type... easy right? Well, if you call the select "type" and try to send that through a jquery ajax call it fails with this error buried deep in jquery.js Don't do this:

$.ajax({
	dataType: "json",
	type: "POST",
	url: "/some_function.php",
	data: { contact_uid:contact_uid, type:type }
});

The problem is that type:type - I believe it is us naming the argument "type" - having a value variable named type isn't the problem. We changed this to:

$.ajax({
	dataType: "json",
	type: "POST",
	url: "/some_function.php",
	data: { contact_uid:contact_uid, contact_type:type }
});

And rewrote some_function.php accordingly - problem solved.

Solution 12 - Javascript

In my case, I basically forget to get the value of input.

Wrong

let name=document.getElementById('name');
param={"name":name}

Correct

let name=document.getElementById('name').value;
param={"name":name}

Solution 13 - Javascript

Nearly every answer here states that this can only be caused by an infinite loop. That's not true, you could otherwise over-run the stack through deeply nested calls (not to say that's efficient, but it's certainly in the realm of possible). If you have control of your JavaScript VM, you can adjust the stack size. For example:

node --stack-size=2000

See also: https://stackoverflow.com/questions/11332422/how-can-i-increase-the-maximum-call-stack-size-in-node-js

Solution 14 - Javascript

In my case, it was that I have 2 variables with the same name!

Solution 15 - Javascript

Sending input elements instead of their values will most likely resolve it like FK mentioned

Solution 16 - Javascript

In my case, two jQuery modals were showing stacked on top of each other. Preventing that solved my problem.

Solution 17 - Javascript

Check if you have a function that calls itself. For example

export default class DateUtils {
  static now = (): Date => {
    return DateUtils.now()
  }
}

Solution 18 - Javascript

For me as a beginner in TypeScript, it was a problem in the getter and the setter of _var1.

class Point2{
    
    constructor(private _var1?: number, private y?: number){}

    set var1(num: number){
        this._var1 = num  // problem was here, it was this.var1 = num
    }
    get var1(){
        return this._var1 // this was return this.var1
    }
}

Solution 19 - Javascript

dtTable.dataTable({
	sDom: "<'row'<'col-sm-6'l><'col-sm-6'f>r>t<'row'<'col-sm-6'i><'col-sm-6'p>>",
	"processing": true,
	"serverSide": true,
	"order": [[6, "desc"]],
	"columnDefs": [
		{className: "text-right", "targets": [2, 3, 4, 5]}
	],
	"ajax": {
		"url": "/dt",
		"data": function (d) {
			d.loanRef = loanRef;
		}
	},
	"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
		var editButton = '';
		// The number of columns to display in the datatable
		var cols = 8;
		// Th row element's ID
		var id = aData[(cols - 1)];
	}
});

In the data function above, I used the same name d.loanRef = loanRef but had not created a variable loanRef therefore recursively declaring itself.

Solution: Declare a loanRef variable or better still, use a different name from the one used on d.loanRef.

Solution 20 - Javascript

Both invocations of the identical code below if decreased by 1 work in Chrome 32 on my computer e.g. 17905 vs 17904. If run as is they will produce the error "RangeError: Maximum call stack size exceeded". It appears to be this limit is not hardcoded but dependant on the hardware of your machine. It does appear that if invoked as a function this self-imposed limit is higher than if invoked as a method i.e. this particular code uses less memory when invoked as a function.

Invoked as a method:

var ninja = {
    chirp: function(n) {
        return n > 1 ? ninja.chirp(n-1) + "-chirp" : "chirp";
    }
};

ninja.chirp(17905);

Invoked as a function:

function chirp(n) {
    return n > 1 ? chirp( n - 1 ) + "-chirp" : "chirp";
}

chirp(20889);

Solution 21 - Javascript

I also faced similar issue here is the details when uploading logo using dropdown logo upload box

<div>
      <div class="uploader greyLogoBox" id="uploader" flex="64" onclick="$('#filePhoto').click()">
        <img id="imageBox" src="{{ $ctrl.companyLogoUrl }}" alt=""/>
        <input type="file" name="userprofile_picture"  id="filePhoto" ngf-select="$ctrl.createUploadLogoRequest()"/>
        <md-icon ng-if="!$ctrl.isLogoPresent" class="upload-icon" md-font-set="material-icons">cloud_upload</md-icon>
        <div ng-if="!$ctrl.isLogoPresent" class="text">Drag and drop a file here, or click to upload</div>
      </div>
      <script type="text/javascript">
          var imageLoader = document.getElementById('filePhoto');
          imageLoader.addEventListener('change', handleImage, false);

          function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {

                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }
      </script>
      </div>

CSS.css

.uploader {
  position:relative;
  overflow:hidden;
  height:100px;
  max-width: 75%;
  margin: auto;
  text-align: center;

  img{
    max-width: 464px;
    max-height: 100px;
    z-index:1;
    border:none;
  }

  .drag-drop-zone {
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.12);
    padding: 32px;
  }
}

.uploader img{
  max-width: 464px;
  max-height: 100px;
  z-index:1;
  border:none;
}



.greyLogoBox {
  width: 100%;
  background: #EBEBEB;
  border: 1px solid #D7D7D7;
  text-align: center;
  height: 100px;
  padding-top: 22px;
  box-sizing: border-box;
}


#filePhoto{
  position:absolute;
  width:464px;
  height:100px;
  left:0;
  top:0;
  z-index:2;
  opacity:0;
  cursor:pointer;
}

before correction my code was :

function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {
                  onclick="$('#filePhoto').click()"
                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }

The error in console:

enter image description here

I solved it by removing onclick="$('#filePhoto').click()" from div tag.

Solution 22 - Javascript

I was facing same issue I have resolved it by removing a field name which was used twice on ajax e.g

    jQuery.ajax({
    url : '/search-result',
    data : {
      searchField : searchField,
      searchFieldValue : searchField,
      nid    :  nid,
      indexName : indexName,
      indexType : indexType
    },
.....

Solution 23 - Javascript

The issue in my case is because I have children route with same path with the parent :

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'prefix' },
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

So I had to remove the line of the children route

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

Solution 24 - Javascript

you can find your recursive function in crome browser,press ctrl+shift+j and then source tab, which gives you code compilation flow and you can find using break point in code.

Solution 25 - Javascript

I know this thread is old, but i think it's worth mentioning the scenario i found this problem so it can help others.

Suppose you have nested elements like this:

<a href="#" id="profile-avatar-picker">
    <span class="fa fa-camera fa-2x"></span>
    <input id="avatar-file" name="avatar-file" type="file" style="display: none;" />
</a>

You cannot manipulate the child element events inside the event of its parent because it propagates to itself, making recursive calls until the exception is throwed.

So this code will fail:

$('#profile-avatar-picker').on('click', (e) => {
    e.preventDefault();

    $('#profilePictureFile').trigger("click");
});

You have two options to avoid this:

  • Move the child to the outside of the parent.

  • Apply stopPropagation function to the child element.

Solution 26 - Javascript

I had this error because I had two JS Functions with the same name

Solution 27 - Javascript

If you are working with google maps, then check if the lat lng are being passed into new google.maps.LatLng are of a proper format. In my case they were being passed as undefined.

Solution 28 - Javascript

Sometimes happened because of convert data type , for example you have an object that you considered as string.

socket.id in nodejs either in js client as example, is not a string. to use it as string you have to add the word String before:

String(socket.id);

Solution 29 - Javascript

in my case I m getting this error on ajax call and the data I tried to pass that variable haven't defined, that is showing me this error but not describing that variable not defined. I added defined that variable n got value.

Solution 30 - Javascript

I was trying to assign a variable, a value, when that variable had not been declared.

Declaring the variable fixed my error.

Solution 31 - Javascript

Have come accross the same issue, coulnd't figured out what's wrong started blaming Babel ;)

Having code not returning any exception in browsers :

if (typeof document.body.onpointerdown !== ('undefined' || null)) {

issue was badly created || (or) part as babel creates its own type check:

function _typeof(obj){if(typeof Symbol==="function"&&_typeof(Symbol.iterator)==="symbol")

so removing

|| null

made babel transpilation worked.

Solution 32 - Javascript

In my case I by mistake i have assigned same variable name , and to val function "class_routine_id"

var class_routine_id = $("#class_routine_id").val(class_routine_id);

it should be Like :

 var class_routine_id = $("#class_routine_id").val(); 

Solution 33 - Javascript

in Angular, if you're using mat-select and have 400+ options, this error may occur https://github.com/angular/components/issues/12504

you have to update @angular/material version

Solution 34 - Javascript

I am using React-Native 0.61.5 along with (npm 6.9.0 & node 10.16.1)

While I am install any new libraries in Project I got an of

(e.g. npm install @react-navigation/native --save)

Maximum call stack size exceeded error

for that, I try

sudo npm cache clean --force

(Note:- Below command usually take time 1 to 2 minutes depending on your npm cache size)

Solution 35 - Javascript

I got this error in express/nodejs app, when the schema of MongoDB database and the models which we have created don't match.

Solution 36 - Javascript

It is intriguingly amazing nobody mentioned await call inside async function. In my case, I have more than 1.5 MB files with loops and database interactions.

async function uploadtomongodb() {

    await find('user', 'user2', myobj0).then(result => {
    }

})

Await will remove "Maximum call stack size exceeded". Otherwise memory loads too much. Not sure if Node can handly more than 700 rows and objects.

Solution 37 - Javascript

The issue might be because of recursive calls without any base condition for it to terminate.

Like in my case, if you see the below code, I had the same name for the API call method and the method which I used to perform operations post that API call.

const getData = async () => {
try {
  const response = await getData(props.convID);
  console.log("response", response);
 } catch (err) {
  console.log("****Error****", err);
}
};

So, basically, the solution is to remove this recursive call.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncopenndthagenView Question on Stackoverflow
Solution 1 - JavascriptalexView Answer on Stackoverflow
Solution 2 - JavascriptlucygenikView Answer on Stackoverflow
Solution 3 - JavascriptFK-View Answer on Stackoverflow
Solution 4 - JavascriptAaron DigullaView Answer on Stackoverflow
Solution 5 - JavascriptSimon_WeaverView Answer on Stackoverflow
Solution 6 - JavascriptNate GlennView Answer on Stackoverflow
Solution 7 - JavascriptShahdatView Answer on Stackoverflow
Solution 8 - JavascriptbendytreeView Answer on Stackoverflow
Solution 9 - JavascriptchimView Answer on Stackoverflow
Solution 10 - JavascriptDr. DamaView Answer on Stackoverflow
Solution 11 - JavascriptScottView Answer on Stackoverflow
Solution 12 - JavascriptAmanView Answer on Stackoverflow
Solution 13 - JavascripthayesgmView Answer on Stackoverflow
Solution 14 - JavascriptNandostyleView Answer on Stackoverflow
Solution 15 - JavascriptEl_boogyView Answer on Stackoverflow
Solution 16 - JavascriptBaz GuvenkayaView Answer on Stackoverflow
Solution 17 - Javascriptonmyway133View Answer on Stackoverflow
Solution 18 - JavascriptReemRashwanView Answer on Stackoverflow
Solution 19 - JavascriptKihatsView Answer on Stackoverflow
Solution 20 - JavascriptElijah LynnView Answer on Stackoverflow
Solution 21 - JavascriptspacedevView Answer on Stackoverflow
Solution 22 - JavascriptTajdar Khan AfridiView Answer on Stackoverflow
Solution 23 - JavascriptAmine HarbaouiView Answer on Stackoverflow
Solution 24 - JavascriptVishal PatelView Answer on Stackoverflow
Solution 25 - JavascriptWeslley RamosView Answer on Stackoverflow
Solution 26 - JavascriptMonir TarabishiView Answer on Stackoverflow
Solution 27 - JavascriptUser-8017771View Answer on Stackoverflow
Solution 28 - JavascriptHussein mahyoubView Answer on Stackoverflow
Solution 29 - Javascriptasifaftab87View Answer on Stackoverflow
Solution 30 - JavascriptPhillip QuinlanView Answer on Stackoverflow
Solution 31 - JavascriptRaphaelView Answer on Stackoverflow
Solution 32 - JavascriptAlok JhaView Answer on Stackoverflow
Solution 33 - JavascriptTalickView Answer on Stackoverflow
Solution 34 - JavascriptHardik DesaiView Answer on Stackoverflow
Solution 35 - JavascriptPriyanshu TiwariView Answer on Stackoverflow
Solution 36 - JavascriptBitfiniconView Answer on Stackoverflow
Solution 37 - JavascriptAkshay ChavanView Answer on Stackoverflow