{"record":{"id":"0ca249a3b86f2dcb","repo":"kestra-io/kestra","slug":"keys-filter-can-only-be-applied-to-list-map-ar","errorCode":null,"errorMessage":"'keys' filter can only be applied to List, Map, Array. Actual type was: {}","messagePattern":"'keys' filter can only be applied to List, Map, Array\\. Actual type was: (.+?)","errorType":"validation","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/filters/KeysFilter.java","lineNumber":45,"sourceCode":"            return inputMap.keySet();\n        }\n\n        if (input instanceof List inputList) {\n            return IntStream\n                .rangeClosed(0, inputList.size() - 1)\n                .boxed()\n                .toList();\n        }\n\n        if (input.getClass().isArray()) {\n            int length = Array.getLength(input);\n            return IntStream\n                .rangeClosed(0, length - 1)\n                .boxed()\n                .toList();\n        }\n\n        throw new PebbleException(null, \"'keys' filter can only be applied to List, Map, Array. Actual type was: \" + input.getClass().getName(), lineNumber, self.getName());\n\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":49,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/filters/KeysFilter.java#L27-L49","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"# before\n{{ outputs.api.body | keys }}\n# after\n{{ outputs.api.body | json | keys }}","handlingStrategy":"type-guard","validationCode":"# Ensure the input is a Map/List before calling keys:\n{% if myvar is iterable and myvar is not string %}\n  {{ myvar | keys }}\n{% else %}\n  []\n{% endif %}","typeGuard":"# Pebble narrowing: `is iterable` excludes scalars; pair with `is not string`\n# to avoid treating a String as an iterable of chars.","tryCatchPattern":null,"preventionTips":["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."],"tags":["pebble-filter","keys","type-mismatch","map","list"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}