kestra-io/kestra · error · IllegalVariableEvaluationException
Unknown value type: {}
Error message
Unknown value type: {} What it means
Thrown by `resolveValues` when `values` is a String that renders to valid JSON but the root node is neither an array nor an object — i.e. a scalar JSON value (number, boolean, string, or null). Iteration requires a collection; a bare scalar is not iterable. The placeholder is the Jackson `JsonNodeType` (e.g. `NUMBER`, `BOOLEAN`, `STRING`).
Source
Thrown at core/src/main/java/io/kestra/core/runners/FlowableUtils.java:450
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());
}
} catch (IOException e) {
throw new IllegalVariableEvaluationException(e);
}
}
case List<?> listValue -> {
List<String> resolvedValues = new ArrayList<>(listValue.size());
for (Object obj : listValue) {
resolvedValues.add(valueAsString(runContext, values, obj));
}
return Either.left(resolvedValues.stream().distinct().toList());
}
case Map<?, ?> mapValue -> {
List<Pair<String, String>> resolvedValues = new ArrayList<>();
for (var entry : ((Map<String, Object>) mapValue).entrySet()) {
resolvedValues.add(Pair.of(entry.getKey(), valueAsString(runContext, values, entry.getValue())));
}
return Either.right(resolvedValues);View on GitHub (pinned to 823fada927)
Solutions
- Ensure the `values` expression renders to a JSON array or object: wrap a scalar in brackets `"[{{ outputs.task.value }}]"`.
- Fix the upstream output/jq to return a collection.
- If iterating key/value pairs, render a JSON object instead of a scalar.
Example fix
# before — renders to a scalar number
values: "{{ outputs.compute.count }}"
# after — wrap into an array
values: "[{{ outputs.compute.count }}]" Defensive patterns
Strategy: validation
Validate before calling
// Ensure rendered values is a JSON array or object
String rendered = runContext.render(valuesExpr);
JsonNode node = MAPPER.readTree(rendered);
if (!node.isArray() && !node.isObject()) {
// wrap scalar into an array
rendered = "[" + rendered + "]";
}
values = rendered; Try / catch
try { FlowableUtils.resolveValues(runContext, values); }
catch (IllegalVariableEvaluationException e) {
if (e.getMessage().startsWith("Unknown value type: ")) {
throw new IllegalVariableEvaluationException(
"Iteration 'values' must render to a JSON array or object, got: " + e.getMessage());
} throw e;
} Prevention
- Always render `values` to a JSON array literal `[...]` or object `{...}`.
- Double-check jq/Pebble filters return collections, not scalars.
- Log the rendered value at DEBUG during development to confirm its shape.
When it happens
Trigger: A ForEach/Loop `values` Pebble expression that renders to a single scalar, e.g. `"{{ outputs.task.value }}"` where `value` is `42` or `true` or a bare word, rather than a JSON array/object. Also triggered when a rendered string is a quoted JSON string `"\"hello\""`.
Common situations: Pointing `values` at a single output instead of a list output; a Pebble expression that returns the first element rather than the whole collection; a misconfigured `jq` filter that selects a scalar field instead of an array.
Related errors
- Found a null value inside the iteration values={}
- Unknown value element type: {}
- QueryFilter must be either a leaf (field + operation) or a n
- Select option object must define a `value` field
- The 'jq' filter expects an argument 'expression'.
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/8fa4b02d27ddeb43.
Report an issue: GitHub.