Quelque chose que je vois constamment dans les workflows n8n en production qui crée de la confusion.
Quand vous activez Continue On Fail sur un nœud, n8n marquera l’exécution comme réussie même si ce nœud a échoué avec un 500, un 401, ou une réponse vide. L’erreur est transmise en aval comme données de sortie d’erreur, le workflow continue de s’exécuter, et le statut d’exécution au niveau supérieur s’affiche en vert.
Cela signifie : votre nœud HubSpot a échoué, votre ligne CRM n’a jamais été créée, votre client n’a jamais reçu l’email — et le journal d’exécution de n8n affiche succès.
Trois endroits où cela cause de réels problèmes :
-
Les nœuds HTTP Request avec Continue On Fail — un 500 d’une API ressemble à l’identique à un 200 dans la vue d’exécution
-
Les nœuds Code qui lèvent des erreurs — passées silencieusement en aval
-
N’importe quel nœud dans un flux multi-étapes où vous « voulez juste qu’il continue »
La solution est d’ajouter un nœud IF explicite après n’importe quel nœud critique qui utilise Continue On Fail — vérifier la présence de $json.error dans la sortie et l’acheminer vers une branche d’alerte.
Quelqu’un d’autre a-t-il rencontré cela en production ? Je serais curieux de savoir comment les gens gèrent cela dans les workflows plus importants.
bonnes améliorations. la forme d’erreur incohérente cause constamment des problèmes aux gens. gérer à la fois $json.error.message et $json.error comme une simple chaîne de caractères dans la même vérification IF est le bon choix.
le cas zéro élément est plus vicieux que CoF sous certains aspects. pas de forme d’erreur, le flux s’arrête simplement, tout ce qui se trouve en amont affiche un statut vert. j’ajoute des vérifications explicites du nombre d’éléments sur les nœuds où une sortie vide est un réel échec, pas juste un cas limité passé sous silence.
sur la configuration : un Error Trigger central pour les défaillances évidentes, mais cela laisse les cas CoF et zéro-éléments non couverts. j’ai construit quelque chose de spécifique pour le modèle green-but-broken. quel est l’endroit le plus courant où vous voyez les zéro éléments causer des problèmes en production ?
Hit this exact thing in production with client-facing report workflows. The inline IF-after-CoF pattern works, but it has one structural weakness: every check lives inside the workflow it’s checking. If the flow stops early (your zero-items case), or someone edits a node and drops the check branch, the validation dies with it — and everything upstream still shows green.
What I converged on: keep the inline checks for routing, but move health validation OUTSIDE the workflow. Each production workflow writes one line of run metadata (status, item counts, timestamp) to a log sheet as its last step; a separate scheduled watcher reads the log and alerts on missing runs, error rows, or zero-count outputs. The watcher survives anything that happens inside the workflows it monitors — including them not running at all, which no inline check can ever catch.
Curious at what scale this starts hurting for people — how many production workflows are you running when you built your CoF discipline?
@dima_automation Pour zéro éléments sortants en production - l’endroit le plus courant que je vois est Google Sheets « Get Rows » avec un filtre qui ne retourne rien (jeton expiré, feuille renommée, plage incorrecte). Le workflow s’exécute proprement avec zéro éléments, chaque nœud en aval produit zéro éléments, et le nœud d’envoi/écriture final ne s’exécute simplement jamais. Pas d’erreur, log vert, le client ne reçoit aucun rapport. Deuxième cas le plus courant : pagination de nœud HTTP Request qui s’arrête prématurément parce que l’API modifie le schéma de réponse et la vérification « has more pages » retourne false. La solution que j’utilise : après n’importe quel nœud où zéro sortie serait un véritable échec, ajouter un nœud IF vérifiant {{ $items().length === 0 }} et router cela vers une alerte explicite plutôt que de continuer silencieusement.
Ces deux cas sont conformes aux manuels, en particulier le Sheets Get Rows avec un filtre qui correspond silencieusement à rien, en aval tout zéro, l’envoi final ne s’exécute jamais, journal vert. C’est la description la plus nette du problème entier que j’aie vue.
Le nœud IF qui vérifie {{ $items().length === 0 }} est la bonne garde de flux où zéro est sans ambiguïté un échec. Une chose qui mérite d’être signalée : elle capture votre premier cas mais pas le second. La sortie de pagination anticipée renvoie un ensemble tronqué mais non nul, donc length === 0 le franchit sans problème, le flux a obtenu 40 lignes sur 200 et chaque nœud est joyeusement non vide. Celui-ci a besoin d’un nombre attendu ou d’une vérification de base, c’est-à-dire est-ce que c’est bien en dessous de ce que cette exécution produit normalement, pas seulement zéro versus pas zéro.
Et les deux modèles supposent toujours que l’exécution s’est produite. La version la plus vicieuse est le flux de travail programmé qui ne s’est jamais déclenché du tout, aucun nœud IF ne s’exécute parce que rien ne s’est exécuté, rien ne se lit comme zéro parce que rien n’a été exécuté. C’est le cas qui m’a poussé à vérifier le résultat de l’extérieur de l’exécution, une garde par nœud ne peut pas protéger une exécution qui n’a pas eu lieu. Votre vérification zéro plus une base de compte plus une vérification de disponibilité extérieure couvre la plupart de la surface entre les deux.