Je poste ceci parce que cela m’a coûté quelques heures et cela échoue silencieusement, ce qui est la pire des combinaisons. Si vous routez quoi que ce soit d’important à travers un nœud IF ou Switch sur un booléen, cela vaut dix minutes de votre temps.
Il y a quelques problèmes ouverts et fils de discussion décrivant ce comportement sans cause profonde attachée. Voici ce que j’ai trouvé.
Le symptôme
J’avais un nœud Switch décidant s’il fallait envoyer une alerte. La sortie du nœud en amont ressemblait à ceci :
{ “shouldEscalate”: true }
Condition Switch : valeur :
{{ $(‘Extract Response’).first().json.shouldEscalate }}
opérateur : Booléen → est vrai
Chaque exécution a routé faux. Aucune erreur. L’exécution a été signalée comme réussie. L’alerte ne s’est tout simplement jamais déclenchée.
Ce que ce n’était pas
J’ai gaspillé du temps sur des hypothèses incorrectes d’abord, donc les voici pour vous épargner le trajet :
• Pas .first() par rapport à .item — j'ai vérifié
• Pas un problème de multi-exécution/lignage d'articles
• Pas le nœud en amont produisant la mauvaise valeur
J’ai prouvé le dernier point en plaçant un nœud Set directement avant le Switch qui émettait la valeur brute plus son type : { “val”: true, “type”: “boolean”, “runs”: 1 }
Vrai booléen. Exécution unique. Valeur correcte arrivant au nœud. Et le Switch l’a toujours envoyé faux.
La cause réelle
n8n rend la sortie d’expression {{ }} sous forme de texte. Donc un vrai booléen true arrive à l’opérateur sous forme de chaîne « true » — et s’il y a un espace blanc ou une nouvelle ligne dans le champ de paramètre après }} (très facile à introduire lors du collage), vous obtenez « true ».
L’opérateur Booléen strict obtient « true », qui n’est pas un booléen, et la comparaison échoue. Silencieusement, dans la direction faux.
Eventuellement, le nœud l’a surfacé verbatim : Type incorrect : « true » est une chaîne mais attendait un booléen
Pourquoi les correctifs évidents n’ont pas fonctionné
J’ai essayé de convertir à l’intérieur de l’expression :
{{ String($(‘Extract Response’).first().json.shouldEscalate).trim().toBoolean() }}
A toujours échoué. L’espace blanc n’est pas à l’intérieur de l’expression — il est introduit après }} lors du propre rendu de n8n. Rien de ce que vous faites à l’intérieur des accolades ne peut l’atteindre.
Basculer « Convertir les types si nécessaire » change le mode d’échec plutôt que de le corriger. Dans mon cas, un paramètre routait tout vrai et l’autre routait tout faux. Les deux sont incorrects ; l’un est juste plus bruyant.
Le correctif qui fonctionne
Arrêtez de comparer le booléen. Émettez un mot-clé explicite et correspondez sur le texte :
valeur : {{ $(‘Extract Response’).first().json.shouldEscalate ? “ESCALATE” : “NORMAL” }}
opérateur : Chaîne → contient
correspondance : ESCALATE
convertir les types : désactivé
« ESCALATE » contient toujours « ESCALATE ». « NORMAL » ne le contient pas non plus de part et d’autre. L’espace blanc final devient inoffensif au lieu d’être fatal.
Vérifié dans les deux directions sur la même version — condition vrai route vrai, condition faux route faux. Cela vaut la peine de faire les deux ; tester uniquement la direction que vous attendez, c’est faire la moitié du test, et ce bug est spécifiquement capable de réussir une direction tout en échouant l’autre.
La version générale
Si un nœud Switch ou IF prend une décision qui a réellement de l’importance — alerte, escalade, filtrage de conformité, n’importe quoi où prendre silencieusement la mauvaise branche est coûteux — ne le routez pas sur un booléen brut. Rendez une chaîne sentinelle et correspondez-la.
« Le mode d’échec ici n’est pas une erreur. C’est une exécution verte qui a fait la mauvaise chose. »