{"record":{"id":"0cf2eb4fd563fe06","repo":"kestra-io/kestra","slug":"could-not-perform-less-than-or-equals-comparison","errorCode":null,"errorMessage":"Could not perform less than or equals comparison","messagePattern":"Could not perform less than or equals comparison","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/expression/LessThanEqualsExpression.java","lineNumber":24,"sourceCode":"import io.pebbletemplates.pebble.template.PebbleTemplateImpl;\nimport io.pebbletemplates.pebble.utils.OperatorUtils;\n\npublic class LessThanEqualsExpression extends BinaryExpression<Boolean> {\n    @Override\n    public Boolean evaluate(PebbleTemplateImpl self, EvaluationContextImpl context) {\n        Object left = this.getLeftExpression().evaluate(self, context);\n        Object right = this.getRightExpression().evaluate(self, context);\n\n        // add support for string comparison\n        if (left instanceof String sLeft && right instanceof String sRight) {\n            return sLeft.compareTo(sRight) <= 0;\n        }\n\n        // default implementation from io.pebbletemplates.pebble.node.expression.LessThanExpression\n        try {\n            return OperatorUtils.lte(left, right);\n        } catch (Exception ex) {\n            throw new PebbleException(\n                ex, \"Could not perform less than or equals comparison\", this.getLineNumber(), self\n                    .getName()\n            );\n        }\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":31,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/expression/LessThanEqualsExpression.java#L6-L31","documentation":"Thrown by the custom LessThanEqualsExpression Pebble node when the '<=' comparison cannot be evaluated. The expression tries string comparison first, then OperatorUtils.lte for numbers; if lte throws due to incomparable operand types, the exception is wrapped with this message.","triggerScenarios":"Using '<=' with mismatched or non-comparable operand types: '{{ mylist <= 10 }}', '{{ null <= 5 }}', '{{ somemap <= \"x\" }}'. One side being null while the other is non-string is the most common trigger.","commonSituations":"Flow conditions comparing outputs that may be null or complex. Threshold checks where the monitored value comes from an upstream task that could produce an unexpected type. Template logic written assuming a numeric output that occasionally resolves to an object.","solutions":["Confirm both operands are strings or numbers before comparison.","Default the variable to a numeric value: '{{ (vars.metric ?? 0) <= 100 }}'.","Add explicit type validation in the upstream task to guarantee the output type."],"exampleFix":"{# before #}\n{% if outputs.task.count <= max_items %}\n\n{# after #}\n{% if (outputs.task.count ?? 0) <= (max_items ?? 100) %}","handlingStrategy":"validation","validationCode":"{# Default both sides to a numeric value before using <= #}\n{% set left = (vars.metric ?? 0) %}\n{% set right = (vars.ceiling ?? 100) %}\n{% if left <= right %}...{% endif %}","typeGuard":"{# Ensure operand is not null or complex before comparing #}\n{% set safe_val = outputs.task.count ?? 0 %}\n{% if safe_val is not null and safe_val is not iterable %}\n  {{ safe_val <= max_items }}\n{% endif %}","tryCatchPattern":null,"preventionTips":["Always provide a numeric fallback with ?? for comparison operands.","Confirm upstream task outputs are typed as integers or numbers.","Test comparison conditions with null and edge-case values."],"tags":["pebble","comparison","less-than-equals","type-mismatch"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}