Flow Doctor

Rubric v1.0 · updated 2026-06-08

Methodology

Flow Doctor is a heuristic linter. It parses your flow YAML in the browser, walks the task tree, and checks it against the failure modes that Kestra users repeatedly hit in production. Each rule is grounded in a public artifact: most map to a real Kestra GitHub issue (the numbers below link straight to them); the Kestra 2.0 · AI rules map to Kestra's stated direction on native agent orchestration rather than a legacy issue number — flagged as such, never dressed up as a fabricated issue. This is an outside-in tool built from public sources; the value is in catching the obvious-in-hindsight gaps before you deploy, not in replacing your own judgement or usage data.

The five dimensions

DimensionMaxWhat it asks
Failure handling25Will a transient error take the whole run down? Checks retry coverage on fallible tasks, flow-level error handling, and a flow timeout.
Observability readiness20When this flow fails, will you be able to see why? Flags loop/subflow patterns whose failures surface poorly today, and fragile expression access.
Scale risk20Will this hold up under load? Flags high-frequency triggers paired with heavy work (worker-memory risk) and sequential-backfill exposure.
Guardrails20Can a single execution run away or stampede? Checks per-task timeouts on long-running work and flow concurrency limits on triggered flows.
YAML hygiene15Is the YAML itself a trap? Detects zero-width/invisible characters, tab indentation, and structural issues that silently break flows.

Every rule, and the issue it maps to

DimensionRuleKestra issue
Failure handlingI/O task (HTTP, script, query, cloud) has no `retry` policy#1246
Failure handlingFlow has fallible tasks but no top-level `errors` block#1246
Failure handlingNo `finally` block for guaranteed teardown#1246
Failure handlingAI / agent task has no retry — providers rate-limit and 5xx constantlyKestra 2.0 · AI
ObservabilityForEach / ForEachItem loop — sub-execution failures surface empty logs/Gantt today#13115, #16495
ObservabilitySubflow task — child logs may not bubble to the parent on failure#13115
ObservabilityFragile field access on `taskrun.value` / loop values#16373
Scale riskHigh-frequency schedule (sub-5-min cron) driving heavy work — worker-memory growth#13129, #6129
Scale riskRealtime / streaming trigger (Debezium, Kafka) — JVM heap pressure under load#6129, #13129
Scale riskScheduled flow — backfills run sequentially, not in parallel#2041
Scale riskAI / agent task fans out inside a loop with no concurrency cap — cost + rate-limit stampedeKestra 2.0 · AI
GuardrailsLong-running task has no `timeout` — a hung step blocks a worker#1493
GuardrailsTriggered flow has no `concurrency` limit — overlapping-execution stampede#1493
GuardrailsAI / agent task has no timeout — a hung or looping call burns tokens indefinitelyKestra 2.0 · AI
GuardrailsNote: Kestra has no flow-level timeout yet — enforce per-task#1493
YAML hygieneInvisible / zero-width character silently breaks parsing#13079
YAML hygieneTab used for indentation (illegal in YAML)#13079

How scoring works

Each dimension starts at full marks. Every finding subtracts a penalty weighted by severity (critical > warning > note), capped so one noisy pattern can't drive a dimension below zero. The total is the sum of the five dimensions, out of 100:

If the YAML fails to parse, structural dimensions are withheld (scored 0) rather than shown as passing — a broken flow should never read as "reliable."

What it deliberately does not do

Built by Roman Martins. Independent and unofficial — not affiliated with Kestra.