Skip to main content
Node Reference

Expression Support

The subset of expression syntax indie.money supports, what is not supported, and when to move logic into a Code node.

Written By Philippe

Last updated 3 days ago

Expression support

Workflows on indie.money support a focused subset of expression syntax. Most everyday expressions work; very complex JavaScript inside an expression does not. When an expression isn't supported, your agent is flagged before it goes live — it won't fail silently.

Supported

  • Nested function expressions — a function inside another function, for example an arrow function whose body builds an array with another arrow function

  • Data access: {{ $json.field }}, {{ $('Node Name').first().json.x }}, {{ $input.item.json.x }}

  • Cross-node helpers: {{ $('Node Name').params }}, {{ $('Node Name').pairedItem(0) }}, {{ $('Node Name').itemMatching($itemIndex) }}

  • Arithmetic and comparisons: {{ $json.price * 2 }}, {{ $json.count > 10 }}

  • Conditionals: ternary {{ $json.ok ? 'yes' : 'no' }}, {{ value || 'default' }}, {{ value ?? 'default' }}

  • Optional chaining: {{ $json.user?.email }}, {{ $json.user?.email ?? 'none' }}

  • Template strings: {{ `Hello ${$json.name}` }}

  • Single array transforms: {{ $json.items.map(x => x.id) }}, {{ $json.items.filter(x => x.active) }}

  • JSON queries: {{ $jmespath($json.items, "[?active].name") }}

  • Helpers: {{ $min(1, 2, 3) }}, {{ $max(...) }}, {{ $sum(...) }}, {{ $if(...) }}, {{ $ifEmpty(...) }}, {{ $now }}, {{ $today }}

Not supported in expressions

  • Wrapping a whole ?? expression in extra parentheses, e.g. {{ ( $json.x ?? 'default' ) }}. Write it without the outer parentheses: {{ $json.x ?? 'default' }}.

How expressions behave

These rules are the same as in n8n:

  • Item tracing — $('Node').item, .pairedItem() and .itemMatching() trace the item back through every node, branching nodes such as IF and Switch included. When the item cannot be traced back, the node stops with n8n's error. It does not return a different item.
  • A failing part of a text — when one {{ }} part of a text throws an error, that part becomes empty text, and the rest of the text renders. An expression error that n8n reports, such as a node that has not run or an item that cannot be traced, still stops the node.
  • A function on the wrong type — a function such as .last() on a value of the wrong type, or on null, stops the node with an error. For example, {{ $json.name.last() }} on a text value stops the node.
  • Time zone — $now, $today and Luxon dates use the workflow's Timezone setting. With no setting, they use UTC.

What to do instead

If an expression is flagged as unsupported, simplify it, or move the logic into a Code node — Code nodes run full JavaScript, including async/await, and can do the complex work, then your expressions just read the result.