windmill-labs/windmill · error · Error::ExecutionErr

Result returned by input transform invalid `{e:#}`

Error message

Result returned by input transform invalid `{e:#}`

What it means

For a suspend step with user_groups_required given as a JavaScript (or other evaluable) input transform, the worker evaluates the expression and expects a Vec<String> of group names. If evaluation fails, the flow job is aborted with "Result returned by input transform invalid".

Source

Thrown at backend/windmill-worker/src/worker_flow.rs:3495

                                     Some(arc_flow_job_args.clone()),
                                     flow_env,
                                     None,
                                     None,
                                     None
                                 )
                                 .warn_after_seconds(3)
                                 .await
                                 .map_err(|e| {
                                     Error::ExecutionErr(format!(
                                         "Error during isolated evaluation of expression `{expr}`:\n{e:#}"
                                     ))
                                 })?
                                 .get(),
                             );
                            if eval_result.is_ok() {
                                user_groups_required = eval_result.ok().unwrap_or(Vec::new())
                            } else {
                                let e = eval_result.err().unwrap();
                                return Err(Error::ExecutionErr(format!(
                                    "Result returned by input transform invalid `{e:#}`"
                                )));
                            }
                        }
                        InputTransform::Ai => {
                            user_groups_required = Vec::new();
                        }
                    }
                } else {
                    user_groups_required = Vec::new();
                };

                let approval_conditions = ApprovalConditions {
                    user_auth_required,
                    user_groups_required,
                    self_approval_disabled,
                };

View on GitHub (pinned to e474e8803c)

Solutions

  1. Fix the JS transform so it returns an array of strings, e.g. ["admins"] or flow_input.x.groups
  2. Ensure 'result'/'previous_result' actually contain the expected data (log via a debug step)
  3. If the groups are fixed, use a Static transform with a proper JSON array instead

Example fix

// before
expr: "result.group"            // result.group may be a string
// after
expr: "Array.isArray(result.group) ? result.group : [result.group]"
Defensive patterns

Strategy: try-catch

Validate before calling

// In the JS transform, guard the value:
const groups = result?.groups;
if (!Array.isArray(groups) || !groups.every(g => typeof g === 'string')) {
  throw new Error('groups must be a string array, got: ' + JSON.stringify(groups));
}
return groups;

Try / catch

let groups: Vec<String>;
match eval_result {
    Ok(g) => groups = g,
    Err(e) => return Err(Error::ExecutionErr(format!("Invalid user_groups_required: {e:#}"))),
}

Prevention

When it happens

Trigger: A suspend step's user_groups_required uses InputTransform::Javascript whose expression throws or returns a non-string-array value at flow runtime.

Common situations: JS expression referencing 'result'/'previous_result' fields that don't exist or aren't arrays; typo in property names; returning a single string instead of an array; flow preceding step output shape changed after a refactor.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/1806add6106bd533. Report an issue: GitHub.