Saltar al contenido principal
JavaScript

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.

Error: RangeError: Maximum call stack size exceeded

¿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 → setStateuseEffect 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.

JavaScriptRangeErrorrecursiónError

¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:

Generador de Prompts

¿Necesitas desarrollo a medida?

Apps web, IA, módulos ERP — cuéntame tu proyecto.