Maximum call stack size exceeded как исправить react

Is this a bug report? YES Did you try recovering your dependencies? npm --version --> 6.4.1 Which terms did you search for in User Guide? I'm trying to create new React application with npx ...

@pabloobandodev

Is this a bug report?

YES

Did you try recovering your dependencies?

npm —version —> 6.4.1

Which terms did you search for in User Guide?

I’m trying to create new React application with npx create-react-app, but I get the following error:

npm ERR! Maximum call stack size exceeded

Environment

System:
OS: macOS 10.14
CPU: x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Binaries:
Node: 8.12.0 — /usr/local/bin/node
npm: 6.4.1 — /usr/local/bin/npm
Browsers:
Chrome: 69.0.3497.100
Firefox: 58.0.2
Safari: 12.0
npmPackages:
react: Not Found
react-dom: Not Found
react-scripts: Not Found
npmGlobalPackages:
create-react-app: 2.0.3

Steps to Reproduce

(Write your steps here:)

  1. I’m trying to create new React application with npx create-react-app, but I get the following error:
  2. Uninstall node, npm, create-react-app and back install and dit it not work
  3. Uninstall node, npm and create-react-app, reinstall them and follow the same error when you run «npx create-react-app my-app»

Expected Behavior

I thought that when executing «npx create-react-app my-app» my my-app project would be created as always.

Actual Behavior

1- I’m trying to create new React application with npx create-react-app, but I get the following error:
screen shot 2018-10-05 at 11 38 13 pm

Reproducible Demo

(Paste the link to an example project and exact instructions to reproduce the issue.)

@aladdin-add

seems the error was from npm, I had seen it some while ago.

@ervandra

I am facing the same issue after cra2 was announced, and cannot seems a good way to fix it.
Trying with npx, npm init, and yarn create, no success.
Have reinstall node 8.x and 10.x
Downgrading and upgrading npm 4.6.x, 5.6.x and 6.4.x
Also delete user’s node_modules and package-lock.json,
Uninstalling yarn globally
But the error stay still.

Main culprit which happened on my local machine is because:

3655 http fetch GET 404 https://registry.npmjs.org/@xtuc%2flong 1866ms
3656 silly fetchPackageMetaData error for @xtuc/long@4.2.1 404 Not Found: @xtuc/long@4.2.1
3657 verbose stack RangeError: Maximum call stack size exceeded

this error log was exposed when installing using yarn 1.10.1 before, since the yarn was removed, the error was found on the error log.

@ryouaki

@ardyfeb

Is there no solution here?

@jd987

I am having the same issue after bumping «react-scripts» to 2.0.4.

xtuc/long fails.
Maximum call stack size exceeded.
I am not behind a proxy. I can navigate to https://registry.npmjs.org/@xtuc/long

@ervandra

After a long days without luck, finally found a great solution and able to run the command npx create-react app awesome-app, npm init react-app awesome-app and create-react-app awesome-app with npm or yarn as well

The culprit was .npmrc file that was located on your user home dir Users/you/.npmrc. once you remove the files, or remove the contents you should be able to init the CRA2 now.

Happy hacking!

orish88, MarcinCholewka, bamaboy, sebasalvarado, dulakm, tekpartner-new, Drilon10, nikitamax, skoropadsky, nickthakkar, and 6 more reacted with thumbs up emoji
tekpartner-new reacted with laugh emoji
Keasoub and evanjmg reacted with confused emoji
skoropadsky and Arwask reacted with heart emoji

@gaearon

Seems like an npm bug but glad that there is a workaround.

If all else fails, install Yarn, and CRA will use Yarn instead.

@sebasalvarado

@gaearon I’m trying to run npx create-react-app my-app I already installed yarn v1.10.1 and this is what I am getting now

Error: Couldn't find package "@xtuc/ieee754@^1.2.0" required by "@webassemblyjs/ieee754@1.7.6" on the "npm" registry.
    at MessageError.ExtendableBuiltin (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:243:66)
    at new MessageError (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:272:123)
    at PackageRequest.<anonymous> (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:33701:17)
    at Generator.throw (<anonymous>)
    at step (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:98:30)
    at /usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:111:13
    at run (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:95053:22)
    at /usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:95070:30
    at flush (/usr/local/Cellar/yarn/1.10.1/libexec/lib/cli.js:94576:9)
    at process._tickCallback (internal/process/next_tick.js:172:11)

EDIT: Looks like there is also an issue open here in the YARN repository. It is really weird why this was not tested.

@shmuelf

Seems like an npm bug but glad that there is a workaround.

If all else fails, install Yarn, and CRA will use Yarn instead.

man, the workaround you mentioned wasn’t helping me (because i don’t have an .npmrc file), but the other thing you mentioned is a 2nd workaround & it did help me — installing yarn solved the problem.

@alivarzeshi

change dir to another drive then run npx create-react-app my-app

@lock
lock
bot

locked and limited conversation to collaborators

Jan 8, 2019

Привет, Хабровчане!

Большинство разработчиков, которые использовали рекурсию для решения своих задач, видели такую ошибку:

 RangeError: Maximum call stack size exceeded. 

Но не каждый разработчик задумывался о том, а что означает «размер стэка вызовов» и каков же этот размер? А в чем его измерять?

Думаю, те, кто работают с языками, напрямую работающими с памятью, смогут легко ответить на этот вопрос, а вот типичный фронтэнд разработчик скорее всего задает себе подобные вопросы впервые. Что-ж, попробуем разобраться!

Многие полагают, что браузер ограничивает нас именно в количестве вызовов, но это не так. В данной статье я покажу на простых примерах, как это работает на самом деле.

О чем ты вообще, автор?

Для статьи важно понимание таких понятий как Execution Stack, Execution Context. Если вы не знаете, что это такое, то советую об этом почитать. На данном ресурсе уже было достаточно хороших статей на эту тему. Пример — https://habr.com/ru/company/ruvds/blog/422089/

Когда возникает эта ошибка?

Разберем на простом примере — функция, которая рекурсивно вызывает сама себя.

const func = () => {
    func();
}

Если попытаться вызвать такую функцию, то мы увидим в консоли/терминале ошибку, о которой я упомянул выше.

А что если подглядеть, сколько же раз выполнилась функция перед тем, как возникла ошибка?

На данном этапе код запускается в Chrome DevTools последней версии на март 2021. Результат будет различаться в разных браузерах. В дальнейшем в статье я упомяну об этом.

Для эксперимента будем использовать вот такой код:

let i = 0;

const func = () => {
  i++;

  func();
};

try {
  func();
} catch (e) {
  // Словили ошибку переполнения стэка и вывели значение счетчика в консоль
  console.log(i);
}

Результатом вывода в консоль стало число в 13914. Делаем вывод, что перед тем, как переполнить стэк, наша функция вызвалась почти 14 тысяч раз.

Магия начинается тогда, когда мы начинаем играться с этим кодом. Допустим, изменим его вот таким образом:

let i = 0;

const func = () => {
  let someVariable = i + 1;
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}

Единственное, что мы добавили, это объявление переменной someVariable в теле функции. Казалось бы, ничего не поменялось, но число стало меньше. На этот раз функция выполнилась 12523 раз. Что более чем на тысячу меньше, чем в прошлом примере. Чтобы убедиться, что это не погрешность, пробуем выполнять такой код несколько раз, но видим одни и те же результаты в консоли.

Почему же так? Что изменилось? Как понять, посмотрев на функцию, сколько раз она может выполниться рекурсивно?!

Магия раскрыта

Отличие второго примера от первого — наличие дополнительной переменной внутри тела функции. На этом все. Соответственно, можно догадаться, именно из-за этого максимальное количество рекурсивных вызовов стало меньше. Что-ж, а что, если у нас будет не одна, а четыре переменных внутри функции? По этой логике, количество рекурсивных вызовов станет еще меньше? Проверим: 

let i = 0;

const func = () => {
  let a = i + 1;
  let b = a + 1;
  let c = b + 1;
  let d = c + 1;
  let e = d + 1;
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}

По этой логике, значение счетчика должно стать еще меньше. Выдыхая, видим вывод — 8945. Ага, оно стало еще меньше. Значит, мы на правильном пути. Хочу привести небольшую аналогию, чтобы даже самым маленьким стало понятно.

Execution Stack (Call Stack) — это емкость с водой. Изначально она пустая. Так получилось, что эта емкость с водой стоит прямо на электрической проводке. Как только емкость переполнится, вода проливается на провода, и мы видим ошибку в консоли. При каждом новом рекурсивном вызове функции в стэк падает капелька воды. Само собой, чем капелька воды крупнее, тем быстрее наполнится стэк.

Емкости бывают разные по размеру. И размер емкости в данном примере — это размер коллстэка. А точнее — количество байт, которое он максимально может в себе удержать. Как гласит статья про Call Stack (Execution Stack), которую я приложил в начале, на каждый вызов функции создается Execution Context — контекст вызова функции (не путать с this). И упрощая, в нем, помимо разных «подкапотных» штук, содержатся все переменные, которые мы объявили внутри функции. Как Execution Context, так и каждая переменная внутри него имеют определенный размер, который они занимают в памяти. Сложив эти два размера мы и получим «размер» капли, которая капает в кувшин при каждом рекурсивном вызове функции.

У нас уже достаточно много данных. Может быть, поэкспериментируем еще? А давайте попробуем вычислить, какой размер коллстэка в движке, который использует Chrome?

Математика все-таки пригодилась

Как мы выяснили, у нас есть две неизвестные, которые составляют размер функции (капельки, которая падает в емкость). Это размер самого Execution Stack, а так же сумма размеров всех переменных внутри функции. Назовем первую N, а вторую K. Сам же неизвестный размер коллстэка обозначим как X.

В итоге — количество байт, которое занимает функция (в упрощенном виде) будет:

FunctionSize = N + K * SizeOfVar

SizeOfVar в данном случае — количество байт, которые занимает переменная в памяти.

Учитывая, что мы знаем количество вызовов первой функции, в теле которой не объявляются переменные, размер коллстэка можно выразить как:

X = (N + 0 *  SizeOfVar)* 13914 = N * 13914

И, для второго случая, возьмем функцию, внутри которой было объявлено пять переменных.

X = (N + 5 * SizeOfVar) * 8945

Иксы в обоих случаях обозначают одно и то же число — размер коллстэка. Как учили в школе, можем приравнять правые части уравнений.

N * 13914 = (N + 5 * SizeOfVar) * 8945

Выглядит неплохо. У нас тут две неизвестные переменные — N и SizeOfVar. Если N мы не можем откуда-то узнать, то что насчет SizeOfVar? Заметим, что во всех функциях, которые фигурировали выше, переменные хранили значение с типом «number», а значит, нужно просто узнать, сколько же байт в памяти занимает одна такая переменная.

С помощью великого гугла получаем ответ — «Числа в JavaScript представлены 64-битными значениями с плавающей запятой. В байте 8 бит, в результате каждое число занимает 64/8 = 8 байт.» Вот она — последняя неизвестная. 8 байт. Подставляем ее в наше уравнение и считаем, чем равно N.

N * 13914 = (N + 5 * 8) * 8945

Упрощаем:

N * 13914 = N * 8945 + 40 * 8945

Если выразить отсюда N, то получим ответ: N равно приблизительно 72. В данном случае 72 байтам.

Теперь, подставив N = 72 в самое первое уравнение, получим, что размер коллстэка в Chrome равен… 1002128 байтов. Это почти один мегабайт. Не так уж и много, согласитесь.

Мы получили какое-то число, но как убедиться, что наши расчеты верны и число правильное? А давайте попробуем с помощью этого числа спрогнозировать, сколько раз сможет выполниться функция, внутри которой будет объявлено 7 переменных типа ‘number’. 

Считаем: Ага, каждая функция будет занимать (72 + 7 * 8) байт, это 128. Разделим 1002128 на 128 и получим число… 7829! Согласно нашим расчетам, такая функция сможет рекурсивно вызваться именно 7829 раз! Идем проверять это в реальном бою…

Мы были очень даже близки. Реальное число отличается от теоретического всего на 3. Я считаю, что это успех. В наших расчетах было несколько округлений, поэтому результат мы посчитали не идеально, но, очень-очень близко. Небольшая погрешность в таком деле — нормально.

Получается, что мы посчитали все верно и можем утверждать, что размер пустого ExecutionStack в Chrome равен 72 байтам, а размер коллстэка — чуть меньше одного мегабайта.

Отличная работа!

Важное примечание

Размер стэка разнится от браузера к браузеру. Возьмем простейшую функцию из начала статьи. Выполнив ее в Сафари получим совершенно другую цифру. Целых 45606 вызовов. Функция с пятью переменными внутри выполнилась бы 39905 раз. В NodeJS числа очень близки к Chrome по понятным причинам. Любопытный читатель может проверить это самостоятельно на своем любимом движке JavaScript. 

А что с непримитивами?

Если с числами все вроде бы понятно, то что насчет типа данных Object? 

let i = 0;

const func = () => {
  const a = {
    key: i + 1,
  };
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}

Простейший пример на ваших глазах. Такая функция сможет рекурсивно вызваться 12516. Это практически столько же, сколько и функция с одной переменной внутри. Тут в дело вступает механизм хранения и передачи объектов в JS’е — по ссылке. Думаю, большинство уже знают об этом.

А что с этим? А как поведет себя вот это? А что с *?

Как вы заметили, экспериментировать можно бесконечно. Можно придумать огромное количество кейсов, которые будут прояснять эту ситуацию глубже и глубже. Можно ставить эксперименты при разных условиях, в разных браузерах, на разных движках. Оставляю это на тех, кого эта тема заинтересовала.

Итоги:

  • Количество рекурсивных вызовов функции до переполнения стэка зависит от самих функций.

  • Размер стэка измеряется в байтах.

  • Чем «тяжелее» функция, тем меньше раз она может быть вызвана рекурсивно.

  • Размер стэка в разных движках различается.

Вопрос особо любознательным: А сколько переменных типа «number» должно быть объявлено в функции, чтобы она могла выполниться рекурсивно всего два раза, после чего стэк переполнится?

Ситуация: заказчик попросил разместить на странице кликабельную картинку, а чтобы на неё обратило внимание больше посетителей, попросил сделать вокруг неё моргающую рамку. Логика моргания в скрипте очень простая:

  1. В первой функции находим на странице нужный элемент.
  2. Добавляем рамку с какой-то задержкой (чтобы она какое-то время была на экране).
  3. Вызываем функцию убирания рамки.
  4. Внутри второй функции находим тот же элемент на странице.
  5. Убираем рамку с задержкой.
  6. Вызываем первую функцию добавления рамки.

Код простой, поэтому делаем всё в одном файле:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Pulse</title>
	<style type="text/css">
	/*	рамка, которая будет моргать	*/
		.pulse { box-shadow: 0px 0px 4px 4px #AEA79F; }
	</style>
</head>
<body>
	<div id="pulseDiv"> 
    	<a href="#">
      		<div id="advisersDiv">
        		<img src="https://thecode.media/wp-content/uploads/2020/08/photo_2020-08-05-12.04.57.jpeg">
        	</div>
      	</a>
</div>
<!-- подключаем jQuery -->
<script src="https://yastatic.net/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<!-- наш скрипт -->
<script type="text/javascript">
	// добавляем рамку
	function fadeIn() {
		// находим нужный элемент и добавляем рамку с задержкой
  	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
  	// затем убираем рамку
  	fadeOut();
	};
	// убираем рамку
	function fadeOut() {
		// находим нужный элемент и убираем рамку с задержкой
   	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
   	// затем добавляем 
   	fadeIn();
	};
	// запускаем моргание рамки
	fadeIn();
</script>

</body>
</html>

Но при открытии страницы в браузере мы видим, что ничего не моргает, а в консоли появилась ошибка:

❌ Uncaught RangeError: Maximum call stack size exceeded

Что это значит: в браузере произошло переполнение стека вызовов и из-за этого он не может больше выполнять этот скрипт.

Переполнения стека простыми словами означает вот что:

  1. Когда компьютер что-то делает, он это делает последовательно — 1, 2, 3, 4.
  2. Иногда ему нужно отвлечься от одного и сходить сделать что-то другое — а, б, в, г, д. Получается что-то вроде 1, 2, 3 → а, б, в, г, д → 4.
  3. Вот эти переходы 3 → а и д → 4 — это компьютеру нужно запомнить, что он выполнял пункт 3, и потом к нему вернуться.
  4. Каждое запоминание, что компьютер бросил и куда ему нужно вернуться, — это называется «вызов».
  5. Вызовы хранятся в стеке вызовов. Это стопка таких ссылок типа «когда закончишь вот это, вернись туда».
  6. Стек не резиновый и может переполняться.

Что делать с ошибкой Uncaught RangeError: Maximum call stack size exceeded

Эта ошибка — классическая ошибка переполнения стека во время выполнения рекурсивных функций.

Рекурсия — это когда мы вызываем функцию внутри самой себя, но чуть с другими параметрами. Когда параметр дойдёт до конечного значения, цепочка разматывается обратно и функция собирает вместе все значения. Это удобно, когда у нас есть чёткий алгоритм подсчёта с понятными правилами вычислений.

В нашем случае рекурсия возникает, когда в конце обеих функций мы вызываем другую: 

  1. Функции начинают бесконтрольно вызывать себя бесконечное число раз.
  2. Стек вызовов начинает запоминать вызов каждой функции, чтобы, когда она закончится, вернуться к тому, что было раньше.
  3. Стек — это определённая область памяти, у которой есть свой объём.
  4. Вызовы не заканчиваются, и стек переполняется — в него больше нельзя записать вызов новой функции, чтобы потом вернуться обратно.
  5. Браузер видит всё это безобразие и останавливает скрипт.

То же самое будет, если мы попробуем запустить простую рекурсию слишком много раз:

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Как исправить ошибку Uncaught RangeError: Maximum call stack size exceeded

Самый простой способ исправить эту ошибку — контролировать количество рекурсивных вызовов, например проверять это значение на входе. Если это невозможно, то стоит подумать, как можно переделать алгоритм, чтобы обойтись без рекурсии.

В нашем случае проблема возникает из-за того, что мы вызывали вторые функции бесконтрольно, поэтому они множились без ограничений. Решение — ограничить вызов функции одной секундой — так они будут убираться из стека и переполнения не произойдёт:

<script type="text/javascript">
// добавляем рамку
function fadeIn() {
	// находим нужный элемент и добавляем рамку с задержкой
	$('#pulseDiv').find('div#advisersDiv').delay(400).addClass("pulse");
	// через секунду убираем рамку
	setTimeout(fadeOut,1000)
};
// убираем рамку
function fadeOut() {
	// находим нужный элемент и убираем рамку с задержкой
 	$('#pulseDiv').find('div#advisersDiv').delay(400).removeClass("pulse");
 	// через секунду добавляем рамку
	setTimeout(fadeIn,1000)
};
// запускаем моргание рамки
fadeIn();
</script>

Что означает ошибка Uncaught RangeError: Maximum call stack size exceeded

Вёрстка:

Кирилл Климентьев

The «Uncaught RangeError: Maximum call stack size exceeded» error occurs in JavaScript when you don’t specify an exit condition for your recursive function. Take the following as an example:

const test = () => test()

// ❌ This will throw "Uncaught RangeError: Maximum call stack size exceeded"
test()

Copied to clipboard!

This function will call itself indefinitely, causing the «Maximum call stack size exceeded» error. You may also come across this error in other forms, such as the below, but the cause will be the same.

"Uncaught InternalError: Too much recursion"

To fix the error, we will need to provide an exit condition. You can do this by wrapping the call inside a conditional statement. Take the following code as an example:

const countDown = num => {
    if (num > 0) {
        console.log(num)
        countDown(num - 1)
    }
}

Copied to clipboard!

This is also a recursive function that calls itself and will log out numbers until it reaches 0. Notice that we call the function with the «same argument — 1». This means that at a certain call, the condition will not be met, meaning we will stop executing the function. This way, we won’t reach the maximum call stack size, as we have an exit condition.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.

Master JavaScript


Infinite loops

The «Maximum call stack size exceeded» error can not only happen with recursive functions, but with infinite loops as well. Most commonly, this can happen while using a while loop.

A common way to ensure that your while loop has an exit condition is to decrement a value at each iteration. Take a look at the following example:

i = 100

while (i--) {
    console.log(i)
}

Copied to clipboard!

Once i reaches 0, it will be evaluated as false, meaning we will stop executing the while loop. In this case, this is our exit condition.

Make sure you always define an exit condition to avoid running into infinite loops.

Want to learn more about recursion in JavaScript? Check out the below tutorial.

An Easy Way to Understand Recursion in JavaScript

An Easy Way to Understand Recursion in JavaScript

Recursion demonstrated through practical examples

Learn recursion in and out in JavaScript by learning how to generate file trees.

The JavaScript RangeError: Maximum call stack size exceeded is an error that occurs when there are too many function calls, or if a function is missing a base case.

Error message:

RangeError: Maximum call stack size exceeded

Error Type:

RangeError

What Causes RangeError: Maximum Call Stack Size Exceeded

The RangeError: Maximum call stack size exceeded is thrown when a function call is made that exceeds the call stack size. This can occur due to the following reasons:

  • Too many function calls.
  • Issues in handling recursion, e.g. missing base case in a recursive function to stop calling itself infinitely.
  • Out of range operations.

RangeError: Maximum Call Stack Size Exceeded Example

Here’s an example of a JavaScript RangeError: Maximum call stack size exceeded thrown when using a recursive function that does not have a base case:

function myFunc() {
    myFunc();
}

myFunc();

Since the recursive function myFunc() does not have a terminating condition (base case), calling it creates an infinite loop as the function keeps calling itself over and over again until the RangeError: Maximum call stack size exceeded error occurs:

Uncaught RangeError: Maximum call stack size exceeded
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)
    at myFunc (test.js:2:2)

How to Avoid RangeError: Maximum Call Stack Size Exceeded

If this error is encountered when calling recursive functions, it should be ensured that the function has a defined base case to terminate the recursive calls.

In case this error occurs due to an excessive number of function calls or variables, these should be reduced as much as possible. Any out of range operations should also be checked and avoided. These issues can be inspected using the browser console and developer tools.

The earlier example can be updated to include a base case:

function myFunc(i) {
    if (i >= 5) {
        return;
    }
    myFunc(i+1);
}

myFunc(1);

The above code avoids the error since recursive calls terminate when the base case is met.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing JavaScript errors easier than ever. Sign Up Today!

Понравилась статья? Поделить с друзьями:
  • Max payne an error has occurred in the graphics engine
  • Max payne 3 ошибка при запуске приложения 0xc0000906
  • Max payne 3 ошибка недостаточно памяти
  • Max payne 3 ошибка недостаточно места на жестком диске
  • Math domain error python asin