Chuyển tới nội dung chính

Expressions and templating

Almost every string in a flow can hold an expression: the text between {{ and }}. Egret renders expressions with a port of Kestra's Pebble template language, so most Kestra expressions work unchanged. This page lists what is available, with the results seen when each was run on a demo instance, and what is not supported yet.

Write an expression​

tasks:
- id: say_hello
type: io.kestra.plugin.core.log.Log
message: "{{ vars.greeting }}, {{ inputs.customer | upper }}! Today is {{ now() | date('yyyy-MM-dd') }}."

An expression has a value, optionally followed by filters (| upper) and function calls (now()). A value can be a name from the context, a literal or a calculation.

You writeYou get
{{ 1 + 2 * 3 }}7
{{ 10 / 4 }}2.5
{{ 7 % 3 }}1
{{ 'a' ~ 'b' }}ab (join text)
{{ true and not false }}true
{{ 'x' in ['x', 'y'] }} and {{ 'x' isIn ['x', 'y'] }}true
{{ vars.n > 2 ? 'big' : 'small' }}big (ternary)
{{ vars.missing ?? 'fallback' }}fallback (when the value is missing or null)
{{ vars.missing ??? 'undef' }}undef (only when the attribute is missing)

Text and numbers keep their type: {{ inputs.orders + 1 }} adds when orders is an INT input. Use double quotes around the YAML string and single quotes inside the expression, as above, so the YAML stays valid.

Statements​

{% %} blocks work for control structures and loops:

- id: list_items
type: io.kestra.plugin.core.log.Log
message: |
{% for i in inputs.items %}[{{ i }}]{% endfor %}

With items set to ["a", "b", "c"] this prints [a][b][c].

What a task can read​

These names are available when a task renders. All of them were confirmed in a run.

NameWhat it isExample
inputsThe flow's input values.{{ inputs.customer }}
varsThe flow's variables:, plus any set by SetVariables.{{ vars.env }}
outputsOutputs of tasks that have finished.{{ outputs.summary.value }}
labelsThe execution's labels.{{ labels.team }}
flowThe flow: id, namespace.{{ flow.id }}
executionThe execution: id, startDate, state.{{ execution.id }}
taskThe current task: id, type.{{ task.type }}
taskrunThe current task run: id, and value inside a loop.{{ taskrun.id }}
itemIn a Loop: value, index, and key for a map.{{ item.value }}
parent, parentsThe enclosing task run or runs, inside nested tasks.
kv('key')A value from the namespace's KV store.{{ kv('support_email') }}

A name that does not exist stops the task with an undefined value error unless you give a fallback with ??. Two reasons you might hit it: the task you read has not finished yet, or the name is not provided. These are not provided today: trigger (so {{ trigger.date }} fails in a scheduled run), envs, globals, execution.originalId and flow.revision.

An id with a dash needs brackets: {{ outputs['first-task'].value }}. The editor refuses the dotted form.

Filters​

Apply a filter with |. These are registered:

GroupFilters
Textcapitalize, title, upper, lower, trim, replace, escape, escapeChar, slugify, startsWith, endsWith, split, substringBefore, substringBeforeLast, substringAfter, substringAfterLast, indent, nindent, urldecode
Regular expressionsregexExtract, regexMatch, regexReplace
Numbersabs, number, format
Lists and mapsfirst, last, join, length, reverse, sort, slice, distinct, flatten, chunk, keys, values
Dates and timedate, dateAdd, timestamp, timestampMilli, timestampMicro, timestampNano
Formats and hashestoJson, toIon, yaml, jq, md5, sha1, sha512
Otherdefault, string, className

Verified examples:

ExpressionResult
{{ inputs.name | upper }}EGRET WORKFLOWS
{{ inputs.name | title }}Egret Workflows
{{ 'egret workflows' | slugify }}egret-workflows
{{ inputs.nothing | default('fallback') }}fallback
{{ inputs.items | join('-') }}a-b-c
{{ '2026-10-19T08:30:00Z' | date('yyyy/MM/dd HH:mm') }}2026/10/19 08:30
{{ '2026-10-19' | date('EEEE') }}Monday
{{ 'order-1042' | regexExtract('[0-9]+') }}1042
{{ 'a1b2' | regexReplace('[0-9]', '#') }}a#b#
{{ '%05d' | format(42) }}00042
{{ inputs.items | toJson }}["a","b","c"]
{{ '{"a":1}' | jq('.a') | first }}1

Date patterns follow Java's DateTimeFormatter, so yyyy-MM-dd HH:mm:ss and EEEE behave as in Kestra. The filters urlencode, base64encode and base64decode are not available yet. The number filter accepts only text input.

Functions​

GroupFunctions
Timenow(), dayOfMonth, dayOfWeek, hourOfDay, monthOfYear, isWeekend, isDayWeekInMonth, isLastWorkingDay, isPublicHoliday (needs a country code)
Identifiers and numbersuuid(), id(), ksuid(), nanoId(), randomInt(lower, upper), randomPort(), range(from, to) (inclusive)
ParsingfromJson, fromIon, yaml
ExecutiontasksWithState('SUCCESS'), loopOutputs, fetchContext, printContext
Storage and filesread, fileSize, fileExists, isFileEmpty, fileURI (these read execution files)
Storekv('key')

The time, identifier, parsing and kv functions were run on a demo instance. fileExists and its siblings answer for files an execution wrote, and refuse other URIs. Not supported yet: max, min, currentEachOutput, render and errorLogs (each answers not implemented yet and fails the task). http() is refused on purpose, because an expression renders inside the control plane and a request from there would leave from the server's own network. secret() is refused everywhere except on Kestra plugin tasks; the editor reports secret_outside_plugin_task and a flow that calls it also needs the workflow:use_secrets permission to be saved.

How rendering behaves​

  • Rendering repeats. A value that renders to text that itself contains an expression is rendered again, up to 100 times.
  • Strict variables. A missing name is an error, not an empty string. Use ?? for optional values.
  • Raw text. Wrap text in {% raw %} … {% endraw %} to print braces literally.
  • Output limits. A rendered value has a size cap, and a task fails with a message naming the cap when it is crossed.
  • Errors. A failing expression fails its task with a message such as undefined value (in <string>:1), shown in the Logs tab.
mẹo

Test an expression before you build on it: put it in a Log task with allowFailure: true, run the flow, and read the line in the Logs tab.

Limits and known issues​

  • trigger.* is not available in task expressions, so a scheduled or webhook flow cannot read the trigger's date or body. The execution's Overview tab shows the trigger's variables.
  • YAML inputs are text in expressions.
  • errorLogs(), render(), max() and min() fail. See Retries, errors and timeouts for how to react to a failure without errorLogs().

Further reading​