kestra-io/kestra · error · PebbleException
'keys' filter can only be applied to List, Map, Array. Actua
Error message
'keys' filter can only be applied to List, Map, Array. Actual type was: {} What it means
Thrown by the 'keys' Pebble filter when the input is not a Map, List, or Java array. The filter dispatches on these three types and falls back to this error for anything else (String, Number, Boolean, or null-safe non-collections). The message reports the actual Java class so the caller can see what was passed.
Source
Thrown at core/src/main/java/io/kestra/core/runners/pebble/filters/KeysFilter.java:45
return inputMap.keySet();
}
if (input instanceof List inputList) {
return IntStream
.rangeClosed(0, inputList.size() - 1)
.boxed()
.toList();
}
if (input.getClass().isArray()) {
int length = Array.getLength(input);
return IntStream
.rangeClosed(0, length - 1)
.boxed()
.toList();
}
throw new PebbleException(null, "'keys' filter can only be applied to List, Map, Array. Actual type was: " + input.getClass().getName(), lineNumber, self.getName());
}
}
View on GitHub (pinned to 823fada927)
Solutions
- Parse the input first: `{{ outputs.fetch.body | json | keys }}` if the body is a JSON string.
- Confirm the variable is actually a Map by printing it (`{{ myvar }}`) before applying `keys`.
- Switch to a filter that matches the actual type (e.g. `length` for strings).
Example fix
# before
{{ outputs.api.body | keys }}
# after
{{ outputs.api.body | json | keys }} Defensive patterns
Strategy: type-guard
Validate before calling
# Ensure the input is a Map/List before calling keys:
{% if myvar is iterable and myvar is not string %}
{{ myvar | keys }}
{% else %}
[]
{% endif %} Type guard
# Pebble narrowing: `is iterable` excludes scalars; pair with `is not string` # to avoid treating a String as an iterable of chars.
Prevention
- Print the variable before applying keys to confirm its shape.
- Parse JSON strings with `| json` before calling keys.
- Document expected output types for each task to catch shape drift early.
When it happens
Trigger: Calling `keys` on a scalar variable: `{{ myString | keys }}`, `{{ 42 | keys }}`, `{{ true | keys }}`. Also when a task output that was expected to be a Map resolves to a scalar (e.g. a JSON string instead of a parsed object).
Common situations: Forgetting to parse JSON before calling keys; an upstream task returning a different shape than expected after a plugin version change; misreading the output spec.
Related errors
- 'chunk' filter can only be applied to List. Actual type was:
- Input must be a list, but received : {}
- The 'flatten' filter can only be applied to lists.
- An error occurred while flattening the list.
- 'number' filter can only be applied to String. Actual type w
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/0ca249a3b86f2dcb.
Report an issue: GitHub.