Pourquoi mon nœud Code ne retourne qu'un seul élément alors que le nœud précédent en produit 200 ?

J’appelle une API externe en utilisant le nœud HTTP Request. L’API met parfois du temps à répondre, j’ai donc activé l’option de nouvelle tentative. Le problème est que certaines requêtes finissent par créer des enregistrements en double dans le système externe.

Décrivez le problème/l’erreur/la question

D’après l’historique d’exécution, il semble que la requête soit relancée même si la première requête a peut-être atteint l’API. Y a-t-il un moyen d’empêcher cela sans désactiver complètement les nouvelles tentatives ?

Quel est le message d’erreur (le cas échéant) ?

Veuillez partager votre workflow

(Sélectionnez les nœuds sur votre canevas et utilisez les raccourcis clavier CMD+C/CTRL+C et CMD+V/CTRL+V pour copier et coller le workflow.)

Partagez le résultat renvoyé par le dernier nœud

Informations sur votre configuration n8n

  • Version n8n : 1.123.x
  • Base de données (par défaut : SQLite) :
  • Paramètre EXECUTIONS_PROCESS de n8n (par défaut : own, main) :
  • Exécution de n8n via (Docker, npm, n8n cloud, application de bureau) :
  • Système d’exploitation :

Salut @Amidu_Louis Bienvenue dans la communauté et oui, tu peux garder les tentatives. Les doublons viennent de la façon dont « Retry On Fail » fonctionne : il réexécute le nœud entier, pas seulement la requête qui a échoué. Le nœud HTTP Request envoie chaque élément qu’il a reçu, et si l’un d’eux génère une erreur, le nœud échoue et la tentative envoie à nouveau tous les éléments, y compris ceux qui ont déjà créé leur enregistrement.

Place le nœud HTTP Request à l’intérieur d’une boucle « Loop Over Items » avec « Batch Size » défini sur 1, afin que chaque exécution du nœud traite un élément et qu’une tentative ne renvoie que celui-ci. Si l’API supporte une clé d’idempotence (Stripe l’appelle l’en-tête Idempotency-Key), envoie également une clé qui reste identique entre les tentatives, comme un ID provenant de tes propres données, afin qu’une requête qui a expiré après avoir atteint l’API ne puisse pas créer un deuxième enregistrement non plus.

Cela vaut la peine de vérifier Options > Timeout sur le nœud également. Une fois que tu ajoutes cette option, elle prend par défaut 10 secondes, donc une réponse plus lente compte comme un échec et est renvoyée en tentative.

La boucle d’un seul élément n’aide que si plusieurs éléments d’entrée atteignent le nœud HTTP Request et qu’une nouvelle tentative rejoue les frères et sœurs réussis. Elle ne résout pas le cas de timeout dans votre question : la même requête a peut-être déjà créé l’enregistrement avant que la réponse soit perdue

Je vérifierais d’abord si la destination accepte une clé d’idempotence stable. Si ce n’est pas le cas, conservez une référence d’opération dérivée de la logique métier et réconciliez la destination avant de réessayer un résultat ambigu. Un simple drapeau « vu » local ne peut pas prouver que l’écriture distante a échoué

Une chose à ajouter aux suggestions Loop Over Items + idempotency : pour un POST non-idempotent, je n’utiliserais pas du tout la fonction Retry On Fail intégrée au nœud HTTP Request. Elle ne peut pas distinguer un timeout (où la requête a peut-être déjà créé l’enregistrement) d’un vrai échec.

À la place, réglez ce nœud sur On Error > Continue (en utilisant la sortie d’erreur) et construisez votre propre retry : si le statut est 429, ou si la connexion a échoué avant l’envoi, attendez quelques secondes et réessayez une ou deux fois. Si c’est un timeout, faites d’abord une recherche GET en utilisant votre propre référence unique pour cet enregistrement, et ne réitérez le POST que s’il n’est pas présent. Traitez un timeout comme étant inconnu, pas comme un échec. L’augmentation des Options > Timeout dans le nœud aide, mais ne supprime pas cette ambiguïté.

Salut @Amidu_Louis, j’espère que tu vas bien

Cela peut se produire lorsque l’API traite la demande mais que n8n ne reçoit pas la réponse à temps. La nouvelle tentative envoie alors la même demande à nouveau. Si l’API prend en charge les clés d’idempotence, utilise une clé unique pour chaque opération afin que les demandes répétées ne créent pas de doublons. Si ce n’est pas le cas, tu devras vérifier si l’enregistrement existe déjà avant de le créer

Les nouvelles tentatives sont utiles, mais pour les demandes POST qui créent des données, elles ne sont pas toujours sûres par elles-mêmes

Un complément à la réponse de Deepankar : après avoir augmenté le délai d’expiration, ouvrez l’une des exécutions dupliquées et regardez l’erreur de la première tentative. Si c’est un timeout/ECONNABORTED plutôt qu’un 5xx, la demande a probablement atteint l’API, et la réessayer aveuglément risquera toujours un doublon. Dans ce cas, désactivez « Retry On Fail », définissez « On Error » sur « Continue (using error output) », et bouclez uniquement sur les erreurs où la demande n’a clairement jamais abouti (429, ECONNREFUSED). Petit conseil : le titre mentionne le nœud Code, donc l’éditer aidera les autres à le trouver.

@Amidu_Louis, un cas limite du conseil « consulter avant réessayer » : une GET vide immédiatement après un délai d’expiration ne prouve pas que le POST original a échoué. La première écriture peut encore être en cours de traitement, ou la consultation peut être en retard sur celle-ci. Un second POST peut alors créer un doublon.

Un test utile dans une API sandbox/mock :

  1. Envoyer l’opération order-123 et retarder son commit jusqu’après l’expiration du délai client.
  2. Faire en sorte que la consultation immédiate ne retourne aucun enregistrement.
  3. Réessayer tandis que la première écriture est encore en attente.
  4. Laisser les deux se terminer et compter les enregistrements pour order-123.

La vérification d’acceptation est un enregistrement distant, même après le redémarrage du flux. Quand c’est possible, conservez et réutilisez la même clé d’idempotence pour cette opération logique, dans la fenêtre de rétention documentée du fournisseur. Une nouvelle clé lors du réessai annule la protection. Une référence métier unique appliquée par le serveur ou un upsert atomique peut également aider si l’API le propose.

Sans l’une ou l’autre garantie, traitez le délai d’expiration comme un résultat inconnu : réconciliez avec des attentes bornées, puis acheminez les cas non résolus pour examen plutôt que de créer aveuglément à nouveau. Un délai d’expiration plus long ou une Taille de lot 1 réduit certaines défaillances mais ne peut garantir une seule écriture distante.

Salut @Amidu_Louis,

C’est Zara du support n8n. Bienvenue dans la communauté !

En prolongeant ce que @Deepankar, @Mahdi_Eqbal et @heroxcreed ont déjà dit : les doublons se produisent parce que Retry On Fail ne peut pas distinguer un délai d’expiration d’un véritable échec. Si l’API a créé l’enregistrement mais la réponse est arrivée tardivement, n8n voit une erreur et renvoie le même POST. Retry réexécute aussi le nœud entier, donc si plusieurs éléments sont en cours et que l’un échoue, ceux qui ont déjà réussi sont renvoyés aussi.

Mettre HTTP Request à l’intérieur de Loop Over Items avec Batch Size 1 corrige le deuxième cas, mais comme Mahdi l’a souligné, cela n’aide pas avec les délais d’expiration. Pour ceux-ci, la meilleure solution est une clé d’idempotence si l’API en supporte une, en utilisant une valeur qui reste la même lors des tentatives, comme un ID de vos propres données (pas une valeur aléatoire générée à l’intérieur du nœud). Si ce n’est pas le cas, suivez l’approche de heroxcreed : désactivez la tentative intégrée pour ce nœud, réglez On Error sur Continue (en utilisant la sortie d’erreur), et en cas de délai d’expiration, effectuez une recherche GET par votre propre référence unique avant de renvoyer le POST. Traitez un délai d’expiration comme « inconnu », pas « échoué ».

Vérifiez aussi Options > Timeout, car il est par défaut défini à 10 secondes une fois ajouté, donc une réponse lente peut déclencher une tentative d’elle-même.

Si vous rencontrez toujours le problème ou si vous avez des questions, n’hésitez pas à écrire à help@n8n.io et notre équipe s’assurera de vous aider.