Generate, debug, and optimize Kestra workflow orchestration YAML files...
Kestra uses declarative YAML to define workflows. Every flow requires id, namespace, and tasks.
id: flow-name # Required: unique within namespace, lowercase with hyphens
namespace: company.team # Required: dot-separated hierarchy
description: | # Optional: supports Markdown
Flow description
labels: # Optional: key-value pairs for organization
env: prod
team: data-engineering
inputs: # Optional: typed parameters
- id: my_input
type: STRING
required: false
defaults: "default value"
variables: # Optional: reusable values
base_url: "https://api.example.com"
tasks: # Required: list of tasks to execute
- id: task-name
type: io.kestra.plugin...
triggers: # Optional: automatic execution
- id: schedule
type: io.kestra.plugin.core.trigger.Schedule
cron: "0 9 * * *"
errors: # Optional: error handling tasks
- id: notify
type: io.kestra.plugin.core.log.Log
message: "Flow failed!"
io.kestra.plugin.[category].[TaskName]{{ inputs.name }}, {{ outputs.taskId.property }}| Type | Description | Example |
|---|---|---|
| STRING | Text value | defaults: "hello" |
| INT | Integer | defaults: 42 |
| FLOAT | Decimal | defaults: 3.14 |
| BOOLEAN | True/false | defaults: true |
| DATETIME | ISO 8601 datetime | defaults: "2024-01-01T00:00:00Z" |
| DATE | ISO 8601 date | defaults: "2024-01-01" |
| TIME | ISO 8601 time | defaults: "09:00:00" |
| DURATION | ISO 8601 duration | defaults: "PT1H" |
| FILE | Uploaded file | (stored in internal storage) |
| JSON | JSON object | defaults: '{"key": "value"}' |
| ARRAY | List of items | itemType: STRING required |
| SELECT | Dropdown | values: [a, b, c] |
- id: log_message
type: io.kestra.plugin.core.log.Log
message: "Hello {{ inputs.name }}!"
level: INFO # DEBUG, INFO, WARN, ERROR
- id: api_call
type: io.kestra.plugin.core.http.Request
uri: "https://api.example.com/data"
method: GET
headers:
Authorization: "Bearer {{ secret('API_TOKEN') }}"
- id: python_task
type: io.kestra.plugin.scripts.python.Script
containerImage: python:3.11-slim
beforeCommands:
- pip install pandas requests
script: |
import pandas as pd
from kestra import Kestra
data = {"result": "success"}
Kestra.outputs(data) # Pass outputs to next tasks
outputFiles:
- "*.csv" # Files to capture
- id: shell_task
type: io.kestra.plugin.scripts.shell.Commands
commands:
- echo "Processing {{ inputs.filename }}"
- cat {{ outputs.download.uri }}
kestra:///, nsfile:///, file:///), fetchType modes, Ion format, read() function, inputFiles/outputFiles, and storage management taskskestra:/// URI auto-resolution, ForEachItem merge outputs, shell quoting, and debugging techniquesTip: If a Kestra MCP server is configured, use it to validate flows, list executions, or trigger runs directly. This skill focuses on generating correct YAML; the MCP server handles runtime interaction.
Tip: If you can't find an answer in the static references, use the Ask Kestra AI API to query their documentation assistant. It's especially useful for:
- Edge cases not covered in common patterns
- Latest plugin features or changes
- Complex output structures (e.g., ForEachItem merging)
- Troubleshooting specific error messages
io.kestra.plugin.core.log.Log){{ }} for Pebble templating{{ secret('SECRET_NAME') }}{{ outputs.taskId.property }}{{ inputs.inputId }}message: "Time: 10:00")| for literal block scalar| Error | Cause | Fix |
|---|---|---|
| "Task type not found" | Plugin not available or typo | Verify exact plugin type string |
| "Invalid YAML syntax" | Bad indentation or special chars | Use 2-space indent, quote strings with : |
| "Variable not found" | Wrong expression syntax | Check {{ outputs.taskId.prop }} format |
| "Required property missing" | Missing required task field | Check plugin docs for required fields |
| "Cannot coerce" | Type mismatch in expression | Verify input/output types match |
| Broken JSON body / 400 errors | User data contains " quotes |
Use {{ value | json }} filter (no surrounding quotes) |
| Fix deployed but restart still fails | restart uses original revision |
Use replay with latest_revision: true instead |