Skip to content

/errors/javascript/maximum-call-stack-size-exceeded

Uncaught RangeError: Maximum call stack size exceeded

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated
tool
JavaScript
exit code
1
versions
ECMAScript 2015+, Node.js 18+, all browsers
os
any

RangeError: Maximum call stack size exceeded means a function kept calling itself (directly or through other functions) until the JavaScript engine ran out of stack frames. In V8 (Chrome, Edge, Node.js) the error is a RangeError; Firefox reports the same problem as InternalError: too much recursion. Almost always it is unbounded recursion: a missing base case, a getter that reads its own property, or two functions that call each other. Look at the repeated frame in the stack trace: that is the function to fix.

Reproduce it

A recursive function with no base case, and a getter that returns its own property:

bash
node -e '
function factorial(n) { return n * factorial(n - 1); }
try { factorial(5); } catch (e) { console.log(`${e.name}: ${e.message}`); }

const user = { get name() { return this.name; } };
try { user.name; } catch (e) { console.log(`${e.name}: ${e.message}`); }
'

Output

RangeError: Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded

Uncaught, Node.js prints the same frame repeated, which points at the culprit:

bash
cat > app.js <<'EOF'
const user = { get name() { return this.name; } };
console.log(user.name);
EOF
node app.js 2>&1 | grep -E "RangeError|at get name" | sort | uniq -c | sed -E 's/^ +[0-9]+ /N× /'

Output

N×     at get name (/tmp/work/app.js:1:41)
N× RangeError: Maximum call stack size exceeded

Fix the recursion

bash
node -e '
function factorial(n) {
  if (n <= 1) return 1;          // base case
  return n * factorial(n - 1);
}
console.log(factorial(5));

class User {
  #name;                         // store the value in a different field
  constructor(name) { this.#name = name; }
  get name() { return this.#name; }
}
console.log(new User("Ada").name);
'

Output

120
Ada

Deep but correct recursion

If the algorithm is right but the input is deep, convert the recursion into a loop with an explicit stack, which lives on the heap and has no frame limit:

js
function sumTree(root) {
  let total = 0;
  const stack = [root];
  while (stack.length) {
    const node = stack.pop();
    total += node.value;
    stack.push(...node.children);
  }
  return total;
}

Spreading a huge array into a function call fails for a similar reason (each element becomes an argument):

bash
node -e '
const big = Array.from({ length: 1_000_000 }, (_, i) => i);
try { Math.max(...big); } catch (e) { console.log(`${e.name}: ${e.message}`); }
console.log(big.reduce((a, b) => (a > b ? a : b)));
'

Output

RangeError: Maximum call stack size exceeded
999999

Sources