Task Runs

A Task Run is a single execution of an individual task within an Execution, where an execution represents a run of the entire flow. One execution can therefore contain multiple task runs.

Each task run includes associated data such as:

  • Execution ID
  • State
  • Start Date
  • End Date

Attempts

A task run can include one or more attempts. Most have only a single attempt, but you can configure retries if needed. When retries are enabled, a task failure triggers new attempts until the maxAttempts or maxDuration threshold is reached.

States

Similar to executions, task runs can exist in different states.

StateDescription
CREATEDThe task run is waiting to be processed, usually queued and not yet started.
RUNNINGThe execution or task run is currently being processed.
SUCCESSThe execution or task run has been completed successfully.
WARNINGThe task run had issues but continued, flagged with a warning.
FAILEDThe task run encountered errors that caused the execution to fail.
RETRYINGThe execution or task run is currently being retried.
RETRIEDAn execution or task run exhibited unintended behavior, stopped, and created a new execution as defined by its flow-level retry policy. The policy was set to the CREATE_NEW_EXECUTION behavior.
KILLINGA kill command was issued and the system is terminating the task run.
KILLEDAn execution or task run was killed (upon request), and no more tasks will run.

Expression

You can access information about the current task run using the {{ taskrun }} expression.

The following example outputs task run details using {{ taskrun }}:

id: taskrun
namespace: company.team
tasks:
- id: return
type: io.kestra.plugin.core.debug.Return
format: "{{ taskrun }}"

The logs show the following:

{
"id": "61TxwXQjkXfwTd4ANK6fhv",
"startDate": "2024-11-13T14:38:38.355668Z",
"attemptsCount": 0
}

Task Run values

Some Flowable tasks, such as ForEach and ForEachItem, group tasks together. You can use {{ taskrun.value }} to access the value of a specific task run.

In the example below, foreach iterates twice over the values [1, 2]:

id: loop
namespace: company.team
tasks:
- id: foreach
type: io.kestra.plugin.core.flow.ForEach
values: [1, 2]
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message:
- "{{ taskrun }}"
- "{{ taskrun.value }}"
- "{{ taskrun.id }}"
- "{{ taskrun.startDate }}"
- "{{ taskrun.attemptsCount }}"
- "{{ taskrun.parentId }}"
- "{{ taskrun.iteration }}"

This produces two separate log entries, one with 1 and the other with 2.

Parent Task Run values

You can also use the {{ parent.taskrun.value }} expression to access a task run value from a parent task within nested flowable child tasks:

id: loop
namespace: company.team
tasks:
- id: foreach
type: io.kestra.plugin.core.flow.ForEach
values: [1, 2]
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message: "{{ taskrun.value }}"
- id: if
type: io.kestra.plugin.core.flow.If
condition: "{{ true }}"
then:
- id: log_parent
type: io.kestra.plugin.core.log.Log
message: "{{ parent.taskrun.value }}"

This iterates through the log and if tasks twice as there are two items in values property. The log_parent task logs the parent task run value as 1 and then 2.

Parent vs. Parents in Nested Flowable Tasks

With nested Flowable tasks, only the immediate parent is available through taskrun.value. To access a parent task higher up the tree, you can use the parent and the parents expressions.

The following flow shows a more complex example with nested flowable parent tasks:

id: each_switch
namespace: company.team
tasks:
- id: simple
type: io.kestra.plugin.core.log.Log
message:
- "{{ task.id }}"
- "{{ taskrun.startDate }}"
- id: hierarchy_1
type: io.kestra.plugin.core.flow.ForEach
values: ["caseA", "caseB"]
tasks:
- id: hierarchy_2
type: io.kestra.plugin.core.flow.Switch
value: "{{ taskrun.value }}"
cases:
caseA:
- id: hierarchy_2_a
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }}"
caseB:
- id: hierarchy_2_b_first
type: io.kestra.plugin.core.debug.Return
format: "{{ task.id }}"
- id: hierarchy_2_b_second
type: io.kestra.plugin.core.flow.ForEach
values: ["case1", "case2"]
tasks:
- id: switch
type: io.kestra.plugin.core.flow.Switch
value: "{{ taskrun.value }}"
cases:
case1:
- id: switch_1
type: io.kestra.plugin.core.log.Log
message:
- "{{ parents[0].taskrun.value }}"
- "{{ parents[1].taskrun.value }}"
case2:
- id: switch_2
type: io.kestra.plugin.core.log.Log
message:
- "{{ parents[0].taskrun.value }}"
- "{{ parents[1].taskrun.value }}"
- id: simple_again
type: io.kestra.plugin.core.log.Log
message:
- "{{ task.id }}"
- "{{ taskrun.startDate }}"

The parent variable gives direct access to the first parent, while the parents[INDEX] gives you access to the parent higher up the tree.

Task Run JSON Object Example
{
"id": "5cBZ1JF8kim8fbFg13bumX",
"executionId": "6s1egIkxu3gpzzILDnyxTn",
"namespace": "io.kestra.tests",
"flowId": "each-sequential-nested",
"taskId": "1-1_return",
"parentTaskRunId": "5ABxhOwhpd2X8DtwUPKERJ",
"value": "s1",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} ⬅ {{taskrun.startDate}}"
},
"value": 45.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} ⬅ {{taskrun.startDate}}"
},
"type": "timer",
"value": "PT0.007213673S"
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2025-05-04T12:02:54.121836Z"
},
{
"state": "RUNNING",
"date": "2025-05-04T12:02:54.121841Z"
},
{
"state": "SUCCESS",
"date": "2025-05-04T12:02:54.131892Z"
}
],
"duration": "PT0.010056S",
"endDate": "2025-05-04T12:02:54.131892Z",
"startDate": "2025-05-04T12:02:54.121836Z"
}
}
],
"outputs": {
"value": "1-1_return > s1 ⬅ 2025-05-04T12:02:53.938333Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2025-05-04T12:02:53.938333Z"
},
{
"state": "RUNNING",
"date": "2025-05-04T12:02:54.116336Z"
},
{
"state": "SUCCESS",
"date": "2025-05-04T12:02:54.144135Z"
}
],
"duration": "PT0.205802S",
"endDate": "2025-05-04T12:02:54.144135Z",
"startDate": "2025-05-04T12:02:53.938333Z"
}
}

Task Runs page (EE)

If your Kestra instance is set up with the Kafka and Elasticsearch backend, you can view Task Runs directly in the UI.

taskrun_view

This view is similar to the Execution View, but displays only task runs.