Workflow Helper Functions
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
This group is more situational, but it becomes valuable in complex flows where you need to inspect sibling results, build links back into Kestra, or summarize failures.
errorLogs()
Prints all error logs from the current execution:
{{ errorLogs() }}It is most useful in errors blocks, where you need a compact summary of what failed without manually traversing task state objects.
currentEachOutput()
Use it inside ForEach flows to avoid manual taskrun.value indexing:
{{ currentEachOutput(outputs.make_data).values.data }}tasksWithState()
Returns a list of task run objects matching the given state. Use it in error handlers or notifications to report which tasks failed:
{{ tasksWithState('FAILED') }}Useful for building conditional logic or failure summaries based on task outcomes.
iterationOutput()
Retrieves the output of a specific iteration from a previous task. Both arguments are optional — taskId defaults to the current task and iteration defaults to the previous iteration:
{{ iterationOutput(outputs.myTask).value }}{{ iterationOutput(outputs.myTask, 2).value }}parentOutput()
Retrieves the output of a parent task. The optional index argument specifies which ancestor to target; omitting it returns the direct parent’s output:
{{ parentOutput() }}{{ parentOutput(1) }}subflow()
Synchronously runs a subflow and returns its terminal execution result, so you can read the subflow’s outputs, state, or labels from within an expression.
{{ subflow(namespace='company.team', id='my_subflow', inputs={'key': 'value'}).outputs.my_output }}Arguments:
| Argument | Required | Description |
|---|---|---|
namespace | Yes | Namespace of the subflow to run |
id | Yes | Flow ID of the subflow to run |
inputs | No | Map of inputs to pass to the subflow |
revision | No | Specific revision to run; defaults to latest |
labels | No | Labels to attach to the subflow execution |
timeout | No | ISO 8601 duration; defaults to PT1M, hard cap PT5M |
Return value — an object with four fields:
| Field | Type | Description |
|---|---|---|
.id | string | Execution ID of the subflow run |
.state | string | Terminal state name, e.g. SUCCESS, FAILED |
.outputs.<key> | any | Flow-level outputs declared in the subflow’s outputs: block |
.labels.<key> | string | Execution labels as a key → value map |
Primary use case — populating a SELECT or MULTISELECT input’s expression: at form render time:
inputs: - id: datacenter type: SELECT expression: "{{ subflow(namespace='company.ops', id='fetch_datacenters').outputs.datacenter_list }}"When a user opens the Execute form, Kestra runs the subflow synchronously, reads its output, and populates the dropdown before the main flow begins.
Important constraints:
- Only valid in an input
expression:context. Usingsubflow()inside a task or trigger property throws an error, because blocking a worker thread while waiting for a child execution can deadlock a worker under load. - Only available on
WEBSERVERandSTANDALONEserver types. The function is not registered on other server types. - The default timeout is
PT1M. The hard cap isPT5M— passing a largertimeoutvalue is rejected at runtime. Both limits are configurable; see configuration reference. - Subflow recursion depth is capped at 3. A subflow whose own inputs call
subflow()counts against this limit. - Executions triggered by
subflow()carry asystem.from: subflowlabel automatically.
appLink()
Enterprise Edition’s appLink() builds links back to Kestra Apps:
{{ appLink(appId='com.example.my-app') }}{{ appLink(baseUrl=true) }}Use it in notifications when you want recipients to jump directly into the related app rather than the generic flow UI.
Was this page helpful?