Módulo 6: Reintentos, alertas y recuperación
2. Reintentos seguros en n8n 2.0
Descripción
Al terminar esta lección vas a poder configurar el reintento automático de un nodo en n8n 2.0 —el setting Retry On Fail, con su número de intentos y su espera entre ellos—, vas a entender qué hace exactamente n8n cuando un nodo falla y se reintenta, y sobre todo vas a saber la regla que decide cuándo activarlo: un reintento solo es seguro si el paso es idempotente. Vas a ver la diferencia entre un fallo transitorio, que un reintento cura solo, y un efecto que un reintento duplica, y vas a aplicar esa distinción a los cuatro workflows de Cumbre. También vas a conocer el caso más traicionero de todos —cuando el efecto sí ocurrió pero la respuesta se perdió— y por qué es la razón real por la que la idempotencia del Módulo 2 no era opcional.
Esto importa porque el reintento es la primera reacción de cualquier sistema ante un fallo, y es también la que más daño hace cuando se activa sin criterio. Una red se cae por medio segundo, una API responde con un error temporal, un servicio está saturado un instante: esos fallos se resuelven solos si simplemente lo intentas de nuevo, y no reintentar significa perder pedidos por nada. Pero reintentar un paso que crea algo —un cobro, un reembolso, una retención— no repite una consulta inofensiva: repite la creación. La diferencia entre un reintento que te salva y uno que le duplica el cobro a un cliente es una sola condición, y esta lección es sobre esa condición.
Conexión con el módulo: la lección 1 te dio el mapa; esta es la primera de las cinco piezas. Los reintentos son la reacción al fallo cuando puedes repetir el efecto sin daño. La lección 3 es la otra cara: qué haces cuando no puedes, y tienes que compensar. Esta lección se apoya de lleno en el Módulo 2 —claves de idempotencia, upserts, el patrón Idempotency-Key— y en un momento vas a ver por qué ese módulo venía antes que este en la guía: sin idempotencia, los reintentos que vas a configurar aquí serían una máquina de duplicados. Guarda en mente el caso de Cumbre: check-credit que coloca una retención, e issue-refund que emite un reembolso. Son los dos protagonistas.
Qué es, exactamente, un reintento
Empecemos por lo más simple, porque la palabra parece obvia y esconde una trampa.
Un reintento es volver a ejecutar un paso que falló, con la esperanza de que la segunda vez funcione. Nada más. Si llamas a alguien y la llamada se corta antes de que conteste, vuelves a marcar. Eso es un reintento.
La analogía que quiero que tengas presente toda la lección es esa misma llamada, pero con un giro. Imagina que mandas un mensaje de texto pidiendo una pizza, y no te llega la confirmación. Tienes dos posibilidades y no puedes distinguir cuál es: o el mensaje nunca llegó a la pizzería, o el mensaje sí llegó y la que se perdió fue la confirmación de vuelta. Si vuelves a mandar el mensaje "por si acaso", en el primer caso arreglaste el problema —ahora sí pediste tu pizza—. Pero en el segundo caso acabas de pedir dos pizzas. Y desde donde tú estás, las dos situaciones se ven idénticas: en ambas, no te llegó la confirmación.
Ese es el corazón de todo. Un reintento no sabe si el paso que falló alcanzó a tener efecto antes de fallar. Reintenta a ciegas. Y por eso la seguridad del reintento no depende del reintento en sí —que siempre es "volver a intentar"— sino de qué tan peligroso es que el efecto ocurra dos veces. Si pedir dos pizzas no te importara —porque tienes un trato con la pizzería de que dos pedidos idénticos en el mismo minuto cuentan como uno—, reintentar sería siempre seguro. Ese trato es, exactamente, la idempotencia.
La anatomía del Retry On Fail en n8n 2.0
n8n te da el reintento como una casilla que activas en cada nodo, sin escribir código. Vamos a ver dónde vive y qué hace cada campo.
Cuando abres cualquier nodo en su panel de detalle, además de los parámetros propios del nodo hay una pestaña de Settings (Configuración). Ahí, entre otras opciones, viven las que nos interesan.
Sobre las etiquetas exactas. Esta guía se escribió con n8n 2.x en julio de 2026. Los nombres de las opciones y sus valores máximos han cambiado entre versiones menores, y son justamente el tipo de dato que conviene verificar en tu propio panel en lugar de confiar de memoria. Cuando el número exacto importe, te lo voy a decir y te voy a pedir que lo confirmes. El concepto no cambia; la etiqueta y el tope, a veces sí.
On Error (Al fallar). Es el primer desplegable, y decide qué hace el nodo cuando algo sale mal, antes de hablar de reintentos. Tiene tres comportamientos, cuyas etiquetas exactas conviene que verifiques en tu versión pero cuyo sentido es estable:
- Detener el workflow (el valor por defecto): si el nodo falla, todo el workflow se detiene ahí y la ejecución queda marcada como fallida. Es lo que quieres para un paso crítico: si no se pudo colocar la retención de crédito, no tiene sentido seguir reservando inventario.
- Continuar (con la salida normal): el workflow sigue como si el nodo hubiera funcionado, pasando lo que pudo al siguiente nodo. Útil para pasos no críticos —si falla el paso que agrega una etiqueta cosmética, el pedido puede seguir—.
- Continuar usando la salida de error: el workflow sigue, pero el item fallido sale por una segunda conexión del nodo, separada de la normal. Esto es potentísimo, porque te deja enrutar los fallos por su propio camino sin detener el flujo —lo vamos a usar en la lección 5 para la cola de mensajes muertos—.
Retry On Fail (Reintentar al fallar). Es la casilla que enciende el reintento automático. Cuando la activas, el nodo, antes de rendirse y aplicar lo que dice On Error, vuelve a intentarse por su cuenta. Al activarla aparecen dos campos más:
- Max Tries (Intentos máximos): cuántas veces intenta el nodo en total antes de darse por vencido. Es el número que decide si tu reintento es un empujoncito o una insistencia. La documentación oficial no fija un valor por defecto ni un tope universal en el texto que consulté; en la interfaz de las versiones recientes el campo está acotado a un número pequeño de intentos, y este es un dato que debes verificar en tu propio panel, porque el tope ha sido un blanco móvil entre versiones. Lo que no cambia es que más intentos no es siempre mejor: cada intento consume tiempo y recursos, y un fallo que no se cura en dos o tres intentos rara vez se cura en diez.
- Wait Between Tries (ms) (Espera entre intentos, en milisegundos): cuánto espera el nodo entre un intento y el siguiente, medido en milisegundos —recuerda, mil milisegundos es un segundo—. La documentación oficial da un ejemplo claro: si la API que llamas permite una petición por segundo, pon
1000para respetar ese límite. Igual que con Max Tries, el valor máximo permitido es algo a verificar en tu panel.
La anatomía completa, entonces, es esta:
Nodo → pestaña Settings
├─ On Error: [ Detener workflow ▾ ] ← qué pasa si al final falla
├─ Retry On Fail: [✓] ← encender el reintento
│ ├─ Max Tries: [ 3 ] ← cuántos intentos en total (verifica el tope)
│ └─ Wait Between Tries: [ 1000 ] ms ← cuánto esperar entre intentos
Un detalle que confunde al principio: Max Tries cuenta el intento original. Si pones 3, el nodo intenta una vez y, si falla, reintenta dos veces más —tres intentos en total, no cuatro—. Verifica en tu panel si tu versión lo cuenta así, pero esa es la convención habitual.
Por qué la espera importa: el backoff
Detengámonos un segundo en el campo de la espera, porque tiene más miga de la que parece.
Si un servicio está caído o saturado, martillarlo con reintentos inmediatos —uno tras otro sin pausa— es contraproducente: le agregas carga justo cuando está débil, y tus reintentos compiten entre sí y con los de todos los demás. Por eso existe la espera entre intentos. Le das al servicio un momento para recuperarse antes de volver a tocarlo.
La idea más fina detrás de esto se llama backoff: en vez de esperar siempre lo mismo, esperas cada vez más entre intento e intento —un segundo, luego dos, luego cuatro—. La lógica es que si el servicio no se recuperó en un segundo, quizás necesite más, y no tiene sentido seguir tocándolo al mismo ritmo. El campo Wait Between Tries de n8n aplica una espera fija —el mismo intervalo entre cada intento—, que para la mayoría de los casos de una automatización de negocio es más que suficiente. Si algún día necesitas un backoff creciente de verdad, se puede construir a mano con un nodo de espera y un bucle, pero eso es un caso avanzado que rara vez hace falta. Por ahora, quédate con la intuición: la espera existe para no golpear un servicio caído, y un poco de espera casi siempre es mejor que ninguna.
Ejemplo trabajado: reintentar check-credit de forma segura
Vamos a poner reintentos en el sistema de Cumbre, empezando por el caso donde son claramente una buena idea. Si tienes una instancia a mano, síguelo; si no, léelo y hazlo después.
El workflow check-credit tiene, en su corazón, un nodo HTTP Request que llama a la API del sistema de crédito de Cumbre para colocar una retención por el monto del pedido. Recuerda una restricción del Módulo 5 que sigue vigente: las llamadas a APIs se hacen con el nodo HTTP Request, no desde un nodo Code —dentro de un nodo Code de n8n 2.0 no puedes hacer peticiones HTTP—. El nodo Code lo usamos solo para preparar datos, como la clave de idempotencia; la llamada la hace el HTTP Request.
Paso 1 — El nodo que tiene el efecto. En check-credit, el nodo HTTP Request llamado Place credit hold hace un POST a la API de crédito con el order_id y el amount. Este es el nodo que a veces da timeout cuando la API está lenta.
Paso 2 — Activar el reintento. Abre ese nodo, ve a la pestaña Settings y activa Retry On Fail. Pon Max Tries en 3 y Wait Between Tries en 1000 (un segundo).
Qué esperar. Con esto, si la API de crédito da timeout en el primer intento, n8n espera un segundo y lo intenta de nuevo, hasta tres veces. Si en cualquiera de esos intentos la API responde bien, el workflow sigue con esa respuesta y nadie se entera de que hubo un tropiezo. Si los tres intentos fallan, el nodo aplica lo que diga On Error —para un paso crítico como este, detener el workflow y marcar la ejecución como fallida, que en la lección 5 vamos a capturar con el Error Trigger—.
Paso 3 — La pregunta que decide si esto es seguro. Aquí está el punto de toda la lección. Reintentar Place credit hold es seguro solo si colocar la retención es idempotente. Y no lo es por sí solo: un POST que dice "coloca una retención de 4820 pesos" ejecutado dos veces coloca dos retenciones. Lo que lo vuelve seguro es la clave de idempotencia del Módulo 2.
Paso 4 — La clave que lo hace seguro. Antes del nodo HTTP Request, un nodo Code calcula una clave de idempotencia estable para este pedido, y esa clave viaja como un header en la petición. La API de crédito está construida para que dos peticiones con la misma clave cuenten como una sola —coloca la retención en la primera y, en la segunda, devuelve la misma retención sin crear otra—. Con eso, reintentar es inofensivo:
// ============================================================
// Nodo: Code — "Build idempotency key" (antes del HTTP Request)
// Modo: Run Once for Each Item
//
// ENTRADA: un pedido de Cumbre con order_id y amount
// SALIDA: el mismo item, con un campo idempotency_key estable
// POR QUÉ: la clave tiene que ser la MISMA en cada reintento,
// para que la API de crédito reconozca la petición repetida
// ============================================================
const order = $json;
// La clave se deriva de datos que NO cambian entre reintentos:
// el order_id identifica el pedido, y "credit-hold" identifica la
// operación. Así, tres reintentos del mismo pedido comparten clave.
const idempotencyKey = `credit-hold:${order.order_id}`;
return {
json: {
...order,
idempotency_key: idempotencyKey, // el HTTP Request lo mandará como header
},
};
En el nodo HTTP Request, ese valor se pone como un header —por ejemplo Idempotency-Key— usando una expresión que lee {{ $json.idempotency_key }}. La API de crédito hace el resto.
Qué esperar del conjunto. Ahora el reintento es una red de seguridad pura. Si la API da timeout después de haber colocado la retención —el caso de las dos pizzas—, el reintento manda la misma clave, la API reconoce que esa retención ya existe, y devuelve la existente sin colocar una segunda. El cliente termina con una retención sin importar cuántas veces se reintentó. Sin esa clave, el mismo reintento habría colocado una segunda retención, y habrías convertido una herramienta de recuperación en una máquina de duplicados.
Lee otra vez el paso 3 y el paso 4 juntos, porque son la lección entera: el reintento no se volvió seguro por configurarlo bien; se volvió seguro porque el efecto que reintenta es idempotente. La casilla Retry On Fail es la parte fácil. La condición para encenderla es todo.
El caso traicionero: cuando el efecto ocurrió pero la respuesta se perdió
Hay un escenario específico que merece su propia sección, porque es el que convierte un reintento aparentemente inofensivo en un duplicado, y es el que más cuesta diagnosticar.
Recuerda la entrega "al menos una vez" del Módulo 1 y la trampa de "verificar y luego actuar" del Módulo 2. Aquí se juntan. Cuando un nodo HTTP Request llama a una API y falla, hay dos mundos posibles detrás de ese fallo, y n8n no puede distinguirlos:
Mundo A — la petición nunca llegó. La red se cayó antes de que la API recibiera nada. El efecto no ocurrió. Reintentar es exactamente lo correcto: ahora sí llega.
Mundo B — la petición llegó, la API hizo el trabajo, y lo que se perdió fue la respuesta de vuelta. La retención se colocó. Pero como la confirmación no volvió, n8n ve un timeout y concluye "falló". Reintentar, en este mundo, coloca una segunda retención.
Desde el punto de vista de n8n, el mundo A y el mundo B se ven idénticos: en ambos, el nodo dio timeout. Es imposible saber cuál ocurrió mirando el error. Y por eso no puedes decidir si reintentar es seguro caso por caso, mirando el fallo. Tienes que hacerlo seguro por diseño, de modo que dé igual en cuál de los dos mundos estés. Eso es, otra vez, la clave de idempotencia: con ella, el mundo B deja de ser un problema, porque el segundo intento con la misma clave no crea nada nuevo.
Esta es la razón profunda de por qué el Módulo 2 venía antes que este. No aprendiste idempotencia como un tema aislado; la aprendiste para poder encender, aquí, la casilla Retry On Fail sin miedo. Un reintento sobre un efecto idempotente es una red de seguridad. Un reintento sobre un efecto que no lo es, es una ruleta rusa que se dispara en el mundo B.
Reintentar el nodo contra reintentar la ejecución
Hay dos niveles distintos donde n8n puede reintentar, y conviene no confundirlos.
Reintento del nodo (el de esta lección): el setting Retry On Fail que acabas de ver. Ocurre dentro de una ejecución, automáticamente, mientras el workflow corre. El nodo falla, espera, se reintenta, y si funciona, la ejecución continúa como si nada. Es la reacción de primera línea a un fallo transitorio.
Reintento de la ejecución completa: cuando una ejecución ya terminó marcada como fallida, n8n te deja volver a lanzarla entera desde la lista de ejecuciones. Ahí verás opciones como Retry with original workflow (reintentar con el workflow tal como estaba) y Retry with currently saved workflow (reintentar con la versión guardada actual, útil si ya arreglaste el bug). Esto no es automático: lo disparas tú, a mano, después del hecho. Es una herramienta de recuperación y de depuración, y la vamos a usar a fondo en la lección 6 para reproducir el bug del duplicado.
La distinción práctica: el reintento del nodo es para fallos transitorios que se curan solos en segundos. El reintento de la ejecución es para cuando el fallo ya quedó registrado y tú decides, con la cabeza fría, volver a procesarlo —quizás después de arreglar algo—. Y ojo con lo mismo de siempre: reintentar una ejecución completa también re-ejecuta los efectos. Si esa ejecución alcanzó a colocar una retención antes de fallar, reintentarla sin idempotencia coloca otra. La misma regla gobierna los dos niveles.
Cuándo NO reintentar
Tan importante como saber activar el reintento es saber cuándo dejarlo apagado. Reintentar no es un default universal; es una decisión.
No reintentes un fallo que no es transitorio. Si la API de crédito responde "el cliente no tiene línea de crédito", eso no es un tropiezo de red: es una respuesta legítima y definitiva. Reintentarla diez veces va a dar diez veces la misma negativa, gastando tiempo para nada. Los reintentos son para fallos transitorios —timeouts, errores temporales del servidor, saturación—, no para fallos lógicos que van a dar el mismo resultado siempre. En términos de códigos HTTP, un 503 Service Unavailable o un 429 Too Many Requests suelen valer la pena reintentar; un 400 Bad Request o un 403 Forbidden no, porque reintentar una petición mal formada o no autorizada da el mismo error.
No reintentes un efecto que no puedes hacer idempotente. Si un paso crea algo y no tienes forma de darle una clave de idempotencia ni de que la API reconozca duplicados, reintentar es peligroso. Para esos casos existe la otra herramienta del módulo: la compensación de la lección 3. No fuerzas el reintento; asumes que puede duplicarse y diseñas cómo deshacer.
No reintentes tantas veces que escondas un problema real. Si un nodo necesita ocho reintentos para funcionar, no tienes un fallo transitorio: tienes un servicio que está sistemáticamente mal y que alguien debería mirar. Poner Max Tries muy alto convierte una alerta legítima en un silencio prolongado. Dos o tres intentos capturan casi todos los tropiezos genuinamente transitorios; más allá de eso, probablemente estás tapando algo que merece una alerta —el tema de la lección 4—.
Errores comunes
Activar Retry On Fail en un nodo que crea algo, sin clave de idempotencia (conceptual). Qué pasa: se activa el reintento en el nodo Place credit hold o en issue-refund "para que sea más robusto", sin la protección de idempotencia. Todo funciona en las pruebas, porque en las pruebas la API responde a la primera. En producción, un día la API responde lento —coloca la retención pero la confirmación se pierde—, n8n reintenta, y aparece una segunda retención. Por qué pasa: el reintento se siente como una mejora inofensiva, y el mundo B —efecto hecho, respuesta perdida— no ocurre casi nunca en desarrollo, así que no se ve venir. Cómo detectarlo: revisa cada nodo con Retry On Fail activado y pregúntate "¿este nodo crea algo?". Si la respuesta es sí, busca la clave de idempotencia que lo protege; si no la hay, tienes un duplicado esperando. Cómo corregirlo: agrega la clave de idempotencia del Módulo 2 antes de encender el reintento, o —si el efecto no se puede hacer idempotente— apaga el reintento y usa la compensación de la lección 3.
Reintentar fallos lógicos como si fueran transitorios (práctico). Qué pasa: se activa el reintento en un nodo que a veces recibe respuestas de negocio negativas —"crédito rechazado", "SKU no existe"— y esos casos se reintentan tres veces dando el mismo resultado, agregando latencia y ensuciando el historial de ejecuciones con fallos que no eran tales. Por qué pasa: el reintento no distingue entre "la red falló" y "la API dijo que no"; reintenta cualquier cosa que el nodo marque como fallo. Cómo detectarlo: mira el historial de ejecuciones de un nodo con reintentos; si ves grupos de tres intentos idénticos que fallan igual, estás reintentando algo que no era transitorio. Cómo corregirlo: distingue en tu diseño el fallo transitorio del resultado de negocio. Una respuesta "crédito rechazado" no debería ser un error del nodo —debería ser una salida normal que un nodo If enruta—, reservando el reintento para timeouts y errores temporales de verdad.
Poner la espera entre intentos en cero (práctico). Qué pasa: se activa el reintento con Wait Between Tries en 0 para que "sea rápido", y cuando la API está saturada, los tres intentos salen casi simultáneos, encuentran el mismo servicio saturado y fallan los tres en una fracción de segundo, sin darle al servicio ninguna oportunidad de recuperarse. Por qué pasa: parece que esperar es perder tiempo, y en el camino feliz lo es —pero el reintento no existe para el camino feliz—. Cómo detectarlo: si tus reintentos fallan todos casi al mismo tiempo que el intento original, no les diste espacio para servir. Cómo corregirlo: pon una espera de al menos un segundo (1000), y más si la API tiene un límite de tasa conocido —la propia documentación de n8n recomienda alinear la espera con ese límite—. Un poco de espera casi siempre recupera más fallos que ninguna.
Ejercicios
Ejercicio 1 — ¿Reintentar o no? Para cada uno de estos cinco pasos de Cumbre, decide si activarías Retry On Fail, y en una frase por qué. Si dirías que sí, di además qué condición tiene que cumplirse para que sea seguro.
(a) Un HTTP Request que consulta el saldo de la línea de crédito de un cliente (solo lee, no modifica nada).
(b) El HTTP Request que coloca la retención de crédito (Place credit hold).
(c) Un nodo Code que calcula el total del pedido a partir de line_items.
(d) El HTTP Request de issue-refund que emite un reembolso.
(e) Un nodo que recibe "crédito rechazado" de la API y decide no surtir el pedido.
Ver solución
(a) Sí, sin condiciones. Es una lectura pura: consultar un saldo no cambia nada, así que repetirla es inofensivo por naturaleza. Reintentar un timeout aquí es siempre seguro. Este es el caso ideal del reintento.
(b) Sí, pero con una condición: la clave de idempotencia. Colocar una retención es un efecto que se puede duplicar. Reintentar es seguro solo si la petición lleva una Idempotency-Key estable y la API reconoce duplicados, como en el ejemplo trabajado. Sin eso, no lo actives.
(c) Sí, aunque casi nunca hará falta. Un cálculo dentro de un nodo Code no llama a nada externo, así que rara vez "falla" por causas transitorias; y si fallara por un dato malo, reintentar daría el mismo error. No hace daño activarlo, pero no aporta: aquí el reintento sobra.
(d) Sí, con la condición más estricta de todas: la clave de idempotencia. Emitir un reembolso es el efecto más peligroso de duplicar del sistema —dinero que sale dos veces—. Reintentar es seguro únicamente con una Idempotency-Key sólida. Este nodo es el que va a protagonizar el bug del duplicado en la lección 6, precisamente porque es donde más duele equivocarse.
(e) No. "Crédito rechazado" no es un fallo transitorio: es una respuesta de negocio definitiva. Reintentarla diez veces da diez rechazos. Este caso ni siquiera debería tratarse como un error del nodo; debería ser una salida normal que un If enruta hacia "pedido no surtido".
Por qué funciona: fíjate en el patrón. Las lecturas (a, c) son seguras de reintentar casi por definición. Los efectos (b, d) son seguros solo con idempotencia. Y los resultados de negocio (e) no se reintentan nunca, porque no son transitorios. Esas tres categorías —lectura, efecto, resultado de negocio— son todo lo que necesitas para decidir.
Ejercicio 2 — El mundo A y el mundo B. El nodo Place credit hold de Cumbre da timeout. Describe qué pasa exactamente cuando n8n lo reintenta, en cada uno de estos dos escenarios, y di en cuál de los dos la clave de idempotencia hace la diferencia:
(a) La petición nunca llegó a la API (mundo A). (b) La petición llegó, la retención se colocó, y lo que se perdió fue la respuesta de vuelta (mundo B).
Ver solución
(a) Mundo A, sin y con clave, se comporta igual. Como la petición nunca llegó, no hay ninguna retención colocada. El reintento manda la petición otra vez, esta vez llega, y la retención se coloca por primera vez. Resultado: una retención. La clave de idempotencia no cambia nada aquí, porque no había ningún duplicado que evitar.
(b) Mundo B es donde la clave decide todo. Sin clave: el reintento manda una petición nueva, la API la ve como un pedido de retención distinto, y coloca una segunda retención. Resultado: dos retenciones, el cliente con el doble bloqueado. Con clave: el reintento manda la misma Idempotency-Key que el intento original; la API reconoce que ya procesó esa clave y devuelve la retención existente sin crear otra. Resultado: una retención.
La conclusión que importa: como n8n no puede distinguir el mundo A del mundo B —los dos se ven como un timeout—, no puedes decidir a mano si reintentar es seguro. La clave de idempotencia hace que dé lo mismo en cuál de los dos mundos estés: en ambos terminas con exactamente una retención. Eso es diseñar la seguridad, en vez de adivinarla.
Por qué funciona: este ejercicio es el corazón de la lección puesto en dos casos concretos. El mundo B es raro —casi nunca ocurre en pruebas— y por eso es tan peligroso: no se ve venir, y cuando aparece en producción, produce un duplicado que nadie entiende. La clave de idempotencia lo neutraliza sin que tengas que saber cuándo ocurrió.
Ejercicio 3 — Diseña la política de reintentos del sistema. Para los cuatro workflows de Cumbre (order-triage, check-credit, inventory-sync, issue-refund), escribe una política de reintentos: en qué nodos activarías Retry On Fail, con qué condición de seguridad, y en cuáles lo dejarías apagado y por qué. No escribas código; escribe las decisiones.
Ver solución
Una política razonable, con las decisiones argumentadas:
order-triage. El nodo que consulta el ledger para deduplicar (una lectura de Postgres) puede reintentarse sin condiciones: leer no daña. La escritura en el ledger que registra el order_id visto conviene reintentarla también, pero solo porque es idempotente por diseño —escribir el mismo order_id dos veces con una restricción de unicidad no crea dos registros, como viste en el Módulo 4—. Los nodos de validación de contrato (Módulo 3) son cálculos: reintentarlos no aporta ni daña.
check-credit. El nodo Place credit hold lleva Retry On Fail activado, con la condición firme de la clave de idempotencia. Max Tries en 2 o 3, con una espera de al menos un segundo. Si tras los reintentos sigue fallando, On Error en "detener el workflow" para que la lección 5 lo capture.
inventory-sync. Depende de cómo esté escrita la reserva. Si es un upsert idempotente por order_id (lo recomendado en el Módulo 2), se reintenta sin miedo. Si por alguna razón fuera un decremento no idempotente, no se activa el reintento: se compensa (lección 3) o se reescribe como upsert primero.
issue-refund. Retry On Fail activado, con la clave de idempotencia más cuidada del sistema, porque duplicar un reembolso es dinero perdido. Es el nodo donde la condición de seguridad es innegociable.
Lo que queda apagado en todo el sistema: cualquier nodo que reciba respuestas de negocio negativas (crédito rechazado, SKU inexistente, stock agotado) no lleva reintento, porque esos no son fallos transitorios sino resultados que hay que enrutar con un If.
Por qué funciona: una política de reintentos no es "actívalo en todos lados" ni "no lo actives en ningún lado". Es una decisión por nodo que responde dos preguntas: "¿el fallo aquí es transitorio?" y "¿si tiene efecto, es idempotente?". Poder escribir esa política para un sistema real es exactamente lo que separa a alguien que configura casillas de alguien que diseña la confiabilidad del sistema —y es, otra vez, la clase de cosa que se defiende en una entrevista mirando tu workflow—.
Resumen y siguiente paso
En esta lección viste que un reintento es simplemente volver a intentar un paso que falló, y que su peligro no está en el reintento sino en el efecto: con la imagen del mensaje de la pizza que no confirma, entendiste que reintentar a ciegas arregla el caso en que el efecto no ocurrió, pero duplica el caso en que sí ocurrió y solo se perdió la respuesta. Conociste la anatomía del Retry On Fail en la pestaña Settings de n8n 2.0 —On Error con sus tres comportamientos, Max Tries y Wait Between Tries, con la advertencia de verificar los topes en tu propio panel— y la idea del backoff para no golpear un servicio caído. Configuraste el reintento de check-credit de Cumbre y viste que lo que lo vuelve seguro no es la casilla, sino la clave de idempotencia del Módulo 2 que viaja en el header. Y desmenuzaste el caso traicionero del mundo A contra el mundo B, que es la razón real por la que la idempotencia venía antes que este módulo en la guía.
Antes de avanzar deberías poder: activar Retry On Fail en un nodo y explicar qué hace cada uno de sus campos; decir por qué reintentar un efecto sin clave de idempotencia es peligroso; y clasificar un nodo de tu sistema como "reintenta sin condición" (lectura), "reintenta solo con idempotencia" (efecto) o "no reintentes" (resultado de negocio o fallo no transitorio).
Lo que no viste todavía es qué hacer con los efectos que no puedes hacer idempotentes. Porque no todo se puede proteger con una clave: a veces un cobro se hizo, un correo se envió, una retención se colocó, y el siguiente paso falla, y no hay forma de "no haberlo hecho". La lección 3 es la otra mitad de la reacción al fallo: cuando no puedes evitar que el efecto ocurra, lo deshaces. Vas a ver el patrón de las acciones compensatorias —por cada "crear" un "anular"—, cómo issue-refund se convierte en la compensación de una retención que quedó huérfana, y por qué un rollback perfecto casi nunca existe en un sistema que toca el mundo real.
Recursos
- Error handling — n8n Docs — la página que reúne los reintentos y el manejo de errores del nodo, incluyendo On Error y Retry On Fail.
- Handling API rate limits — n8n Docs — cómo usar Retry On Fail y Wait Between Tries (ms) para respetar los límites de tasa de una API, con el ejemplo de 1000 ms para una petición por segundo.
- HTTP Request node — n8n Docs — el nodo con el que Cumbre llama a la API de crédito y de reembolsos, donde vive el reintento de sus efectos.
- Handle errors gracefully — n8n Docs — guía oficial sobre las opciones de manejo de errores por nodo y a nivel de workflow.
- Release notes 2.x — n8n Docs — para confirmar la versión que usas y verificar los topes actuales de Max Tries y Wait Between Tries en tu instancia.