{"record":{"id":"c87743ab3a286c21","repo":"kestra-io/kestra","slug":"the-render-function-expects-an-optional-argument","errorCode":null,"errorMessage":"The 'render' function expects an optional argument 'recursive' with type boolean.","messagePattern":"The 'render' function expects an optional argument 'recursive' with type boolean\\.","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/RenderFunction.java","lineNumber":68,"sourceCode":"                null,\n                \"Maximum render() nesting depth (\" + maxDepth + \") exceeded at line \" + lineNumber +\n                    \" — check for circular render() calls in your template.\",\n                lineNumber, self.getName()\n            );\n        }\n\n        if (!args.containsKey(\"toRender\")) {\n            throw new PebbleException(null, \"The 'render' function expects an argument 'toRender'.\", lineNumber, self.getName());\n        }\n        Object toRender = args.get(\"toRender\");\n\n        Object recursiveArg = args.get(\"recursive\");\n        if (recursiveArg == null) {\n            recursiveArg = true;\n        }\n\n        if (!(recursiveArg instanceof Boolean recursive)) {\n            throw new PebbleException(null, \"The 'render' function expects an optional argument 'recursive' with type boolean.\", lineNumber, self.getName());\n        }\n\n        EvaluationContextImpl evaluationContext = (EvaluationContextImpl) context;\n        Map<String, Object> variables = evaluationContext.getScopeChain().getGlobalScopes().stream()\n            .flatMap(scope -> scope.getKeys().stream())\n            .distinct()\n            .collect(HashMap::new, (m, v) -> m.put(v, context.getVariable(v)), HashMap::putAll);\n\n        try {\n            return ((RenderingFunctionInterface) evaluationContext.getExtensionRegistry().getFunction(functionName())).variableRenderer(applicationContext)\n                .renderObject(toRender, variables, recursive, depth + 1).orElse(null);\n        } catch (IllegalVariableEvaluationException e) {\n            throw new PebbleException(e, e.getMessage());\n        }\n    }\n\n    @Override\n    public String functionName() {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/RenderFunction.java#L50-L86","documentation":"The render() function accepts an optional 'recursive' argument that must be a boolean. When provided, it is checked with instanceof Boolean; if it is any other type (string, number, null from an explicit null literal in certain contexts), the function throws. Note that a null value (argument absent) defaults to true, so this only fires when the argument is present but non-boolean.","triggerScenarios":"Passing recursive as a string: {{ render(toRender=x, recursive='true') }}. Passing an integer or a variable that resolves to a non-boolean type. Using a Pebble expression for recursive that evaluates to a string 'false' instead of the boolean false.","commonSituations":"Passing recursive=false as a string literal (quoted) vs boolean literal (unquoted). Dynamic expressions where the variable type is STRING but expected to be BOOLEAN. Copy-pasting from examples that used string values.","solutions":["Use the unquoted boolean literal: {{ render(toRender=x, recursive=false) }} not 'false'.","Ensure any dynamic expression used for recursive resolves to a true Pebble boolean, not a string."],"exampleFix":"# before — string literal\n{{ render(toRender=inputs.x, recursive='false') }}\n\n# after — boolean literal\n{{ render(toRender=inputs.x, recursive=false) }}","handlingStrategy":"type-guard","validationCode":"# Pass recursive as an unquoted boolean literal (true/false), not a string.\n# Correct: {{ render(toRender=x, recursive=false) }}\n# If using a dynamic value, ensure it resolves to a boolean:\n{% set rec = inputs.recursive if inputs.recursive is boolean else true %}{{ render(toRender=x, recursive=rec) }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never quote boolean literals: use false, not 'false'.","If the recursive value comes from a variable, verify its type resolves to boolean.","Test render() calls with both recursive modes in the Kestra UI before deploying."],"tags":["pebble","render","type-error","arguments","boolean"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}