Solución: Maximum call stack size exceeded — bucle infinito de llamadas
JavaScript ha agotado el call stack por recursión infinita o referencias circulares. Cómo identificarlo con el stack trace y las soluciones más comunes.
¿Por qué ocurre?
El motor JavaScript tiene un límite de llamadas apiladas (call stack). Cuando una función se llama a sí misma sin condición de parada (o la condición nunca se alcanza), el stack se llena y explota. También ocurre con JSON.stringify sobre objetos con referencias circulares, o en React cuando un useEffect actualiza el mismo estado que lo dispara.
Solución paso a paso
Caso 1 — Recursión sin caso base:
// ❌ Recursión infinita — no hay caso de parada
function factorial(n) {
return n * factorial(n - 1); // nunca termina
}// ✅ Con caso base
function factorial(n) {
if (n <= 1) return 1; // ← caso base
return n * factorial(n - 1);
}
// ✅ Alternativa iterativa (sin riesgo de stack overflow)
function factorial(n) {
let resultado = 1;
for (let i = 2; i <= n; i++) resultado *= i;
return resultado;
}
Caso 2 — JSON.stringify con referencia circular:
// ❌ El objeto se apunta a sí mismo
const obj = { nombre: 'test' };
obj.self = obj;
JSON.stringify(obj); // RangeError// ✅ Usa un replacer para ignorar referencias circulares
function stringifySeguro(obj) {
const visto = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (visto.has(value)) return '[Circular]';
visto.add(value);
}
return value;
});
}
Caso 3 — useEffect en bucle (React):
// ❌ El efecto actualiza datos, datos dispara el efecto, infinito
useEffect(() => {
setDatos([...datos, nuevoItem]); // ← modifica datos
}, [datos]); // ← depende de datos// ✅ Usa la forma funcional del setter o quita la dependencia
useEffect(() => {
setDatos(prev => [...prev, nuevoItem]);
}, []); // solo al montar
Cómo identificarlo con el stack trace:
Abre DevTools → pestaña Console → haz clic en el error para ver el stack. Si ves la misma función repetida decenas de veces, es recursión. Si ves useEffect → función → setState → useEffect en bucle, es el caso de React.
Cómo evitarlo en el futuro
Toda función recursiva necesita un caso base claramente definido. Para recursiones profundas (árboles, parsers), considera convertirlas a iterativas con una pila manual. En React, revisa siempre que las dependencias del useEffect no sean objetos o arrays que se recrían en cada render.
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts