kestra-io/kestra · error · IllegalArgumentException
Unsupported type for key: {key}, value: {value}
Error message
Unsupported type for key: {key}, value: {value} What it means
The `ListOrMapOfLabelDeserializer` parses a `labels` field that can be either a JSON array of `{key, value}` objects or a JSON map. When parsing the array form, each label's `value` is type-checked via `isAllowedType()`. Only String, Integer, Long, Float, Double, and Boolean are accepted. If the value is a nested object, array, or null (in some cases), an `IllegalArgumentException` is thrown with the offending key and value.
Source
Thrown at core/src/main/java/io/kestra/core/serializers/ListOrMapOfLabelDeserializer.java:35
* This deserializer is for historical purpose, labels was first a map but has been updated to a List of Label so
* this deserializer allows using both types.
*/
public class ListOrMapOfLabelDeserializer extends JsonDeserializer<List<Label>> implements ResolvableDeserializer {
@SuppressWarnings("unchecked")
@Override
public List<Label> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.hasToken(JsonToken.VALUE_NULL)) {
return null;
} else if (p.hasToken(JsonToken.START_ARRAY)) {
// deserialize as list
List<Map<String, String>> ret = ctxt.readValue(p, List.class);
return ret.stream().map(map ->
{
Object value = map.get("value");
if (isAllowedType(value)) {
return new Label(map.get("key"), String.valueOf(value));
} else {
throw new IllegalArgumentException("Unsupported type for key: " + map.get("key") + ", value: " + value);
}
}).toList();
} else if (p.hasToken(JsonToken.START_OBJECT)) {
// deserialize as map
Map<String, Object> ret = ctxt.readValue(p, Map.class);
return ret == null ? null
: ret.entrySet().stream()
.map(this::validateAndCreateLabel)
.toList();
}
throw new IllegalArgumentException("Unable to deserialize value as it's neither an object neither an array");
}
private Label validateAndCreateLabel(Map.Entry<String, Object> entry) {
Object value = entry.getValue();
if (isAllowedType(value)) {
return new Label(entry.getKey(), String.valueOf(value));
} else {View on GitHub (pinned to 823fada927)
Solutions
- Ensure every label value in the array form is a scalar: String, number, or boolean.
- If you need complex metadata, serialize it to a JSON string first.
- Validate the labels payload against the expected schema before submission.
Example fix
# before
labels:
- key: meta
value:
nested: true
# after
labels:
- key: meta
value: '{"nested":true}' Defensive patterns
Strategy: validation
Validate before calling
// Validate label values before serialization
import io.kestra.core.models.Label;
public static List<Label> validateLabels(List<Label> labels) {
for (Label label : labels) {
Object value = label.value();
if (!(value instanceof String || value instanceof Integer || value instanceof Long
|| value instanceof Float || value instanceof Double || value instanceof Boolean)) {
throw new IllegalArgumentException(
"Label '" + label.key() + "' has unsupported value type: " + value.getClass());
}
}
return labels;
} Type guard
function isAllowedLabelValue(v: unknown): boolean {
const t = typeof v;
return t === 'string' || t === 'number' || t === 'boolean';
} Prevention
- Always use scalar values (string, number, boolean) for label values.
- Serialize complex objects to JSON strings before using them as label values.
- Validate the labels payload schema before submitting to the API.
When it happens
Trigger: Submitting a flow or execution with a labels array where a value is a JSON object or array, e.g. `[{"key":"meta","value":{"nested":true}}]`. Providing a null value in the array form.
Common situations: An API consumer sends a complex/nested value where a scalar is expected. A serialization issue causes a value to be sent as a map or list instead of a string.
Related errors
- Unsupported type for key: {entry.getKey()}, value: {value}
- Unable to deserialize value as it's neither an object neithe
- The 'subflow' function 'labels' must be a map of string keys
- The 'subflow' function 'timeout' must be an ISO-8601 duratio
- The 'yaml' function expects an argument 'yaml' with type str
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/9f6a165435bc725a.
Report an issue: GitHub.