windmill-labs/windmill · error
itered cannot be empty
Error message
itered cannot be empty
What it means
In the Windmill flow executor's while-loop/for-loop module handling, when a loop module is first entered and the iterator produced no items (`iter` is empty), the code panics instead of creating zero flow jobs. Windmill treats an empty iteration set as a modeling error for the loop step at this point, because the loop result structure (flow_jobs_success/duration, new_args) cannot be meaningfully constructed from nothing.
Source
Thrown at backend/windmill-worker/src/worker_flow.rs:5901
if itered.is_empty() {
ForLoopStatus::EmptyIterator
} else if *parallel {
ForLoopStatus::ParallelIteration { itered_len: itered.len(), itered }
} else if let Some(first) = itered.first() {
let iter = Iter { index: 0 as i32, value: first.to_owned() };
ForLoopStatus::NextIteration(ForloopNextIteration {
index: 0,
itered_len: itered.len(),
itered,
flow_jobs: vec![],
flow_jobs_success: Some(vec![]),
flow_jobs_duration: Some(FlowJobsDuration::new(0)),
new_args: iter,
while_loop: false,
})
} else {
panic!("itered cannot be empty")
}
}
FlowStatusModule::InProgress {
iterator: Some(FlowIterator { itered, index, .. }),
flow_jobs: Some(flow_jobs),
flow_jobs_success,
flow_jobs_duration,
..
} if !*parallel => {
// Read itered from separate table or fallback to JSONB
let itered = read_itered_from_db(db, flow_job.id, itered).await?;
let itered_new = if itered.is_empty() {
// it's possible we need to re-compute the iterator Input Transforms here, in particular if the flow is being restarted inside the loop
let by_id = if let Some(x) = by_id {
x
} else {View on GitHub (pinned to e474e8803c)
Solutions
- Guard the loop input upstream: add a branch/preprocessor step that skips the loop module when the array is empty.
- Check the loop step's iterator expression and fix it so it produces at least one item, or coerce empty to a sentinel (e.g. loop over `items.length ? items : [null]`).
- If empty loops should be legal, patch worker_flow.rs to return a completed FlowStatus (zero jobs) instead of panicking when `iter` is empty.
- Inspect the flow run logs to see which step produced the empty iterator and fix the producing step.
Example fix
// before
} else {
panic!("itered cannot be empty")
}
// after
} else {
// an empty iterator means the loop is trivially done
return Ok(FlowStatus::WaitingForCompletedJobs(FlowStatusModule::Success {
flow_jobs_success: Some(vec![]),
flow_jobs_duration: Some(FlowJobsDuration::new(0)),
new_args: serde_json::json!([]),
while_loop: false,
}));
} Defensive patterns
Strategy: validation
Validate before calling
// before a for-loop flow step runs, ensure the iterator is non-empty
const items = args.my_list ?? [];
if (!Array.isArray(items) || items.length === 0) {
throw new Error("loop input must be a non-empty array; skip the loop instead");
} Type guard
function isNonEmptyArray(v: unknown): v is unknown[] {
return Array.isArray(v) && v.length > 0;
} Prevention
- Never wire a loop step directly to a list that can be empty; add a branch that bypasses the loop when the array is empty.
- Test flows with empty upstream results (filtering, optional lookups) before deploying.
- Coerce nullable upstream outputs to arrays with defaults at the producing step.
When it happens
Trigger: A for-loop flow step whose input array/iterator expression evaluates to an empty list on the first pass (the `FlowStatusModule::InProgress` branch with no prior `itered` items), so `new_args: iter` would be an empty vec and the executor panics with 'itered cannot be empty'.
Common situations: A flow author wired a loop over a list that is empty at runtime (empty DB result, filtered array, optional input absent); a previous step returns `[]` on first run; skip_if or branching makes the source list empty only in some runs.
Related errors
- unreachable, language is not supported: {language:#?}
- Failed to parse Cargo.toml.default
- header creation
- client build
- cron: a panic occurred during find_next_occurrence
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/80243cf58b242c77.
Report an issue: GitHub.