FlowKit

Les expressions n8n : syntaxe, variables $json et $node, et les erreurs classiques

Publié le 29 juillet 2026 · 5 min de lecture

Les expressions sont le ciment de n8n : chaque champ de node peut contenir, entre doubles accolades, un fragment de JavaScript qui pioche dans les données du workflow. C'est ce qui transforme une suite de nodes statiques en pipeline dynamique — et c'est aussi la première source de confusion des débutants, entre $json, $('Nom du node'), les items et les erreurs [object Object]. Ce guide pose la syntaxe complète, les variables intégrées, et les pièges qui reviennent dans tous les workflows.

La syntaxe de base : des doubles accolades, du JavaScript dedans

Une expression s'écrit {{ ... }} dans n'importe quel champ de node passé en mode Expression (le petit bouton à droite du champ, ou glisser-déposer une donnée depuis le panneau d'entrée). À l'intérieur : du JavaScript standard, évalué pour chaque item qui traverse le node.

Bonjour {{ $json.prenom }}, votre commande {{ $json.commande.id }} est confirmée.
Total TTC : {{ ($json.total_ht * 1.2).toFixed(2) }} €

Tout ce que JavaScript sait faire tient dans une expression : opérations arithmétiques, méthodes de chaînes (.toUpperCase(), .split(), .trim()), ternaires, template literals. La limite est structurelle : une expression renvoie une valeur pour un champ. Dès qu'il faut plusieurs étapes, des boucles ou restructurer les items eux-mêmes, basculez sur le node Code — la frontière entre les deux est le sujet de notre guide expressions et JavaScript dans le node Code.

$json : les données de l'item courant

$json désigne l'objet JSON de l'item en cours de traitement, tel qu'il sort du node précédent :

  • {{ $json.email }} — propriété simple ;
  • {{ $json['Prénom client'] }} — propriété avec espace ou accent (notation crochets obligatoire) ;
  • {{ $json.lignes[0].montant }} — tableaux et objets imbriqués ;
  • {{ $json.adresse?.ville }} — chaînage optionnel pour ne pas planter si adresse est absent.

Le réflexe qui évite 80 % des tâtonnements : glisser-déposer la donnée depuis le panneau d'entrée du node vers le champ. n8n écrit l'expression exacte, chemin imbriqué compris. Et pour vérifier ce que contient réellement $json à un endroit du workflow, le panneau d'entrée en vue JSON fait foi — les techniques de notre guide de débogage s'appliquent.

$('Nom du node') : référencer n'importe quel node en amont

Le node précédent ne suffit pas toujours : après un enrichissement ou un appel IA, on a souvent besoin d'une donnée du webhook initial. C'est le rôle de $('Nom du node') :

{{ $('Webhook').item.json.email }}      → l'item lié dans la sortie du node Webhook
{{ $('Config').first().json.seuil }}     → le premier item de la sortie du node Config
{{ $('Recherche').all().length }}        → le nombre d'items sortis du node Recherche

.item suit la traçabilité des items : n8n retrouve l'item du node référencé dont descend l'item courant — c'est ce qu'il faut dans 90 % des cas. .first(), .last() et .all() ignorent cette liaison et prennent la sortie brute. Deux contraintes : le nom doit correspondre exactement (renommer un node casse les expressions qui le référencent — n8n les met à jour dans l'éditeur, mais méfiance en cas de copier-coller entre workflows), et le node référencé doit avoir été exécuté dans la même branche, sinon l'erreur « Referenced node is unexecuted » tombe.

Les variables intégrées à connaître

  • {{ $now }} et {{ $today }} : la date courante en objet Luxon, d'où l'on tire formatage et arithmétique — {{ $now.minus({days: 7}).toFormat('yyyy-MM-dd') }}. Les subtilités (fuseaux, parsing, différences) sont dans notre guide Luxon des dates et heures ;
  • {{ $workflow.name }}, {{ $workflow.id }}, {{ $execution.id }} : précieux pour tracer les logs et construire des workflows d'erreur parlants ;
  • {{ $env.MA_VARIABLE }} : lit une variable d'environnement du serveur (self-hosted) — la bonne façon d'injecter URL et configuration par environnement, détaillée dans notre guide des variables d'environnement ;
  • {{ $itemIndex }} et {{ $runIndex }} : position de l'item courant et numéro de passage dans une boucle ;
  • {{ $if(condition, siVrai, siFaux) }} et {{ $ifEmpty(valeur, defaut) }} : les deux helpers qui gardent lisibles les champs conditionnels sans ternaires imbriqués.

À cela s'ajoutent les extensions de données propres à n8n, appelées comme des méthodes : {{ $json.email.extractDomain() }}, {{ $json.titre.toSnakeCase() }}, {{ $json.tags.removeDuplicates() }} — des raccourcis documentés dans la référence officielle, qui évitent bien des nodes Code d'une ligne.

Les erreurs classiques et leur diagnostic

  • [object Object] : l'expression renvoie un objet dans un champ texte. Ciblez la propriété ($json.client.nom) ou sérialisez (JSON.stringify($json.client)) ;
  • undefined : le chemin n'existe pas pour cet item — une faute de frappe, ou un item sur dix qui n'a pas le champ. Le chaînage optionnel (?.) et $ifEmpty() rendent l'expression robuste ;
  • « Referenced node is unexecuted » : le node visé n'a pas tourné (autre branche d'un IF, ou pas encore exécuté en mode test). Exécutez le workflow entier avant de tester le node isolé, ou faites converger les branches avant la référence ;
  • Comparer des types différents : $json.montant > "100" fonctionne parfois par coercition, jusqu'au jour où non. Convertissez explicitement (Number($json.montant)), surtout en amont d'un node IF ou Switch.

Ces difficultés n'ont rien d'anecdotique ni de honteux : la recherche en programmation par l'utilisateur final les a formalisées de longue date. L'étude d'Andrew Ko, Brad Myers et Htet Htet Aung, « Six Learning Barriers in End-User Programming Systems » (IEEE Symposium on Visual Languages and Human Centric Computing, 2004, voir sur Google Scholar), identifie précisément les barrières à l'œuvre ici — notamment savoir quelle construction utiliser (barrière de sélection) et comprendre pourquoi le résultat ne correspond pas à l'attendu (barrière de compréhension). Le glisser-déposer d'expressions et l'aperçu en temps réel de n8n sont exactement le genre d'outillage que cette littérature recommande.

Expressions ou Edit Fields : structurer plutôt qu'accumuler

Dernier conseil d'architecture : quand un node accumule cinq expressions complexes dans cinq champs, il est souvent plus lisible de préparer les valeurs en amont dans un node Edit Fields (Set) — une expression par champ nommé, testable isolément — puis de référencer ces champs propres. C'est toute la logique de notre guide du node Set / Edit Fields : les expressions font la transformation, Edit Fields lui donne une forme maintenable.

En résumé

Les expressions n8n, c'est du JavaScript entre {{ }} évalué item par item : $json pour l'item courant, $('Nom du node') pour toute donnée en amont, $now/$env/$if() pour le contexte et les conditions. Maîtrisez la traçabilité des items, convertissez vos types explicitement, et déplacez la complexité vers Edit Fields ou le node Code quand une expression cesse de tenir en une ligne lisible — vos workflows y gagneront autant en robustesse qu'en débogage.

FAQ

Questions fréquentes

Quelle est la différence entre une expression n8n et le node Code ?

Une expression est un fragment JavaScript entre doubles accolades {{ }} évalué dans le champ d'un node, item par item : parfaite pour transformer une valeur à la volée. Le node Code exécute un vrai script sur l'ensemble des items, avec logique multi-lignes, boucles et fonctions. Règle pratique : une ligne, une valeur → expression ; plusieurs étapes ou restructuration des items → node Code.

Comment récupérer une donnée d'un node plus haut dans le workflow, pas seulement du node précédent ?

Avec $('Nom du node') : par exemple {{ $('Webhook').item.json.email }} lit le champ email de l'item correspondant dans la sortie du node Webhook, même si dix nodes ont été exécutés entre les deux. .first() et .last() récupèrent le premier ou dernier item, .all() la liste complète. Attention : le node référencé doit avoir été exécuté dans la même branche.

Pourquoi mon expression affiche-t-elle [object Object] ?

Parce que l'expression renvoie un objet dans un champ qui attend du texte : JavaScript le convertit alors en la chaîne « [object Object] ». Soit vous visez une propriété précise ({{ $json.client.nom }} plutôt que {{ $json.client }}), soit vous sérialisez l'objet avec {{ JSON.stringify($json.client) }} si c'est bien le JSON complet que vous voulez écrire.

Que signifie l'erreur « Referenced node is unexecuted » dans une expression n8n ?

L'expression pointe vers un node qui n'a pas tourné dans l'exécution courante — typiquement parce qu'il se trouve dans une autre branche d'un IF ou d'un Switch, ou en aval. En test, exécutez d'abord le workflow entier ; en production, ne référencez que des nodes situés en amont dans la même branche, ou faites transiter la valeur par un node Edit Fields commun aux deux branches.

Bundle FlowKit Complet

269 €