kestra-io/kestra · error · PebbleException

'chunk' filter can only be applied to List. Actual type was:

Error message

'chunk' filter can only be applied to List. Actual type was: {}

What it means

Thrown by the ChunkFilter when the input to the chunk filter is not a List. The filter can only partition lists into sub-lists; applying it to a string, map, number, or any other type triggers this error.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/filters/ChunkFilter.java:31

public class ChunkFilter implements Filter {
    @Override
    public List<String> getArgumentNames() {
        return List.of("size");
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Object apply(Object input, Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) throws PebbleException {
        if (input == null) {
            return null;
        }

        if (!args.containsKey("size")) {
            throw new PebbleException(null, "'chunk' filter expects an argument 'size'.", lineNumber, self.getName());
        }

        if (!(input instanceof List)) {
            throw new PebbleException(null, "'chunk' filter can only be applied to List. Actual type was: " + input.getClass().getName(), lineNumber, self.getName());
        }

        Object sizeObj = args.get("size");
        if (!(sizeObj instanceof Number)) {
            throw new PebbleException(null, "'chunk' filter argument 'size' must be a number. Actual type was: " + sizeObj.getClass().getName(), lineNumber, self.getName());
        }
        return Lists.partition((List) input, ((Number) sizeObj).intValue());
    }
}

View on GitHub (pinned to 823fada927)

Solutions

  1. Ensure the input variable is a list before calling chunk: wrap single values with '[...]' or verify the upstream output type.
  2. Use a conditional to handle non-list cases: '{% if myvar is iterable %}{{ myvar | chunk(10) }}{% endif %}'.
  3. Fix the upstream task to always produce a list output.

Example fix

{# before #}
{{ outputs.task.value | chunk(5) }}
{# outputs.task.value is a string #}

{# after — ensure list #}
{{ [outputs.task.value] | chunk(5) }}
Defensive patterns

Strategy: type-guard

Validate before calling

{# Ensure the input is a list before calling chunk #}
{% set input = outputs.task.value %}
{% if input is iterable %}
  {{ input | chunk(10) }}
{% else %}
  {{ [input] | chunk(10) }}
{% endif %}

Type guard

{# Pebble 'is iterable' test narrows to list-like types #}
{% if myvar is iterable %}
  {{ myvar | chunk(5) }}
{% endif %}

Prevention

When it happens

Trigger: Calling chunk on a non-list value: '{{ mystring | chunk(2) }}', '{{ mymap | chunk(3) }}', '{{ 42 | chunk(5) }}'. The input variable resolves to a type other than List at runtime.

Common situations: A task output that is sometimes a list and sometimes a single object or string, and the template assumes it is always a list. Passing a JSON object (map) where a JSON array (list) was expected.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/b96e06cbed3a0c2f. Report an issue: GitHub.