kestra-io/kestra · error · IllegalVariableEvaluationException
Found a null value inside the iteration values={}
Error message
Found a null value inside the iteration values={} What it means
Thrown by `FlowableUtils.resolveValues` when the `values` of an iteration task (ForEach, Parallel, etc.) is a String that renders to a JSON **array**, and at least one element of that array is JSON `null`. The placeholder is the serialized original `values` object, included so the developer can see the full offending input.
Source
Thrown at core/src/main/java/io/kestra/core/runners/FlowableUtils.java:432
*
* @return a list of String with no duplicates if the values were a list, or a list of pairs of String/String if the values were a map.
* @throws IllegalVariableEvaluationException in case of JSON error, unsupported value type or duplicate values.
*/
public static Either<List<String>, List<Pair<String, String>>> resolveValues(RunContext runContext, Object values) throws IllegalVariableEvaluationException {
switch (values) {
case String stringValue -> {
String renderValue = runContext.render(stringValue);
try {
JsonNode valuesNode = MAPPER.readTree(renderValue);
if (valuesNode.isArray()) {
List<String> resolvedValues = MAPPER.convertValue(valuesNode, TYPE_REFERENCE)
.stream()
.map(throwFunction(obj ->
{
if (obj instanceof String s) {
return s;
} else if (obj == null) {
throw new IllegalVariableEvaluationException(
"Found a null value inside the iteration values=" + serializeAsString(values)
);
} else {
return serializeAsString(obj);
}
}))
.distinct()
.toList();
return Either.left(resolvedValues);
} else if (valuesNode.isObject()) {
List<Pair<String, String>> resolvedValues = new ArrayList<>();
Map<String, Object> mapValues = MAPPER.convertValue(valuesNode, JacksonMapper.MAP_TYPE_REFERENCE);
for (var entry : mapValues.entrySet()) {
resolvedValues.add(Pair.of(entry.getKey(), valueAsString(runContext, values, entry.getValue())));
}
return Either.right(resolvedValues);
} else {
throw new IllegalVariableEvaluationException("Unknown value type: " + valuesNode.getNodeType());View on GitHub (pinned to 823fada927)
Solutions
- Filter nulls out of the rendered array before iteration: `{{ mylist | filter(v => v != null) }}`.
- Fix the upstream source so no array element is null.
- If null is meaningful, replace it with a sentinel string (e.g. "null" or "") in the source data.
Example fix
# before
tasks:
- id: loop
type: io.kestra.plugin.core.flow.ForEach
values: "{{ outputs.query.rows }}" # rows may contain null entries
# after — drop nulls
values: "{{ outputs.query.rows | filter(r => r != null) }}" Defensive patterns
Strategy: validation
Validate before calling
// Strip nulls from a JSON-array string before resolveValues
String rendered = runContext.render(valuesExpr);
JsonNode node = MAPPER.readTree(rendered);
if (node.isArray()) {
List<Object> clean = new ArrayList<>();
node.forEach(n -> { if (!n.isNull()) clean.add(MAPPER.treeToValue(n, Object.class)); });
values = MAPPER.writeValueAsString(clean);
} Try / catch
try {
Either.leftOrRight(FlowableUtils.resolveValues(runContext, values));
} catch (IllegalVariableEvaluationException e) {
if (e.getMessage().startsWith("Found a null value")) {
runContext.logger().error("Iteration values contained null; filtering them out.");
// re-run after filter
} else throw e;
} Prevention
- Sanitize iteration sources with a Pebble filter: `{{ list | filter(v => v != null) }}`.
- Prefer non-nullable columns in upstream SQL/query outputs.
- Add a data-quality task before the loop to reject null rows.
When it happens
Trigger: A ForEach/Loop task whose `values` is a Pebble expression that renders to a JSON array containing a null entry, e.g. `["a", null, "c"]` or `[{"x":1}, null]`. Common when the expression reads from a nullable output field or a sparse JSON/CSV source.
Common situations: Iteration over a list that has gaps; reading rows from a file/API where a row is null; a `{{ outputs.task.rows | jq(...) }}` that yields nulls for missing columns; mapping over an array of optionals.
Related errors
- Unknown value type: {}
- Unknown value element type: {}
- QueryFilter must be either a leaf (field + operation) or a n
- Select option object must define a `value` field
- Found a null value in the ION file
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/bcb8b8421b97e87a.
Report an issue: GitHub.