{"record":{"id":"59c411787c410b5b","repo":"kestra-io/kestra","slug":"the-loopoutputs-function-expects-outputs-to-be","errorCode":null,"errorMessage":"The 'loopOutputs' function expects 'outputs' to be a list.","messagePattern":"The 'loopOutputs' function expects 'outputs' to be a list\\.","errorType":"validation","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/LoopOutputsFunction.java","lineNumber":42,"sourceCode":"\n    @Override\n    public List<String> getArgumentNames() {\n        return ARGUMENT_NAMES;\n    }\n\n    @Override\n    public Map<String, String> getArgumentDefaults() {\n        return ARGUMENT_DEFAULTS;\n    }\n\n    @Override\n    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {\n        Object outputsArg = args.get(ARG_OUTPUTS);\n        if (outputsArg == null) {\n            throw new PebbleException(null, \"The 'loopOutputs' function expects a non-null argument 'outputs'.\", lineNumber, self.getName());\n        }\n        if (!(outputsArg instanceof List<?>)) {\n            throw new PebbleException(null, \"The 'loopOutputs' function expects 'outputs' to be a list.\", lineNumber, self.getName());\n        }\n\n        Object nameArg = args.get(ARG_NAME);\n        if (nameArg == null) {\n            throw new PebbleException(null, \"The 'loopOutputs' function expects a non-null argument 'name'.\", lineNumber, self.getName());\n        }\n        if (!(nameArg instanceof String)) {\n            throw new PebbleException(null, \"The 'loopOutputs' function expects 'name' to be a string.\", lineNumber, self.getName());\n        }\n\n        String key = (String) nameArg;\n        List<?> loopOutputs = (List<?>) outputsArg;\n        List<Object> result = new ArrayList<>(loopOutputs.size());\n\n        for (Object loopOutputObj : loopOutputs) {\n            if (loopOutputObj instanceof Map<?, ?> loopOutput) {\n                Object iterationOutputs = loopOutput.get(ITERATION_OUTPUTS_KEY);\n                result.add(iterationOutputs instanceof Map<?, ?> outputs ? outputs.get(key) : null);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/LoopOutputsFunction.java#L24-L60","documentation":"The loopOutputs() function checks that the 'outputs' argument is an instance of List<?>. If it is non-null but not a list (e.g. a Map, a String, or a single Object), this type-check error fires. Loop task iteration outputs are expected to be a list of per-iteration output maps.","triggerScenarios":"Passing a single task's outputs instead of a Loop's iteration list (e.g. outputs.myTask instead of outputs.myLoop.outputs). Passing a Map or a String where a List is expected. The referenced task is not a Loop task and its outputs have a different shape.","commonSituations":"The author confuses a regular task's output map with a Loop's iteration list. The upstream task type changed from a ForEach/Loop to a single-execution task.","solutions":["Ensure the outputs argument points to a Loop task's outputs, which is a list: outputs.<loopTaskId>.outputs.","If the data is a single object, restructure the logic — loopOutputs is designed for iteration lists only."],"exampleFix":"# before (regular task output, not a list)\nvalue: \"{{ loopOutputs(outputs.myTask, 'result') }}\"\n# after (Loop task iteration outputs)\nvalue: \"{{ loopOutputs(outputs.myLoop.outputs, 'result') }}\"","handlingStrategy":"type-guard","validationCode":"# Verify the argument is a list before calling:\n{% if outputs.myLoop.outputs is iterable %}\n  {{ loopOutputs(outputs.myLoop.outputs, 'myOutput') }}\n{% else %}\n  {{ throw('loopOutputs expects a list') }}\n{% endif %}","typeGuard":"# Pebble 'is iterable' test narrows list types:\n{% if myVar is iterable %}...{% endif %}","tryCatchPattern":null,"preventionTips":["Only pass Loop task iteration outputs (which are lists) to loopOutputs.","Do not pass regular task output maps to loopOutputs — use direct property access instead.","Verify the upstream task type is a Loop/ForEach before referencing its outputs."],"tags":["pebble-function","loopoutputs","type-mismatch"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}