{"record":{"id":"5dd7694c008ac0d1","repo":"kestra-io/kestra","slug":"could-not-perform-greater-than-comparison","errorCode":null,"errorMessage":"Could not perform greater than comparison","messagePattern":"Could not perform greater than comparison","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/expression/GreaterThanExpression.java","lineNumber":24,"sourceCode":"import io.pebbletemplates.pebble.template.PebbleTemplateImpl;\nimport io.pebbletemplates.pebble.utils.OperatorUtils;\n\npublic class GreaterThanExpression 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.GreaterThanExpression\n        try {\n            return OperatorUtils.gt(left, right);\n        } catch (Exception ex) {\n            throw new PebbleException(\n                ex, \"Could not perform greater than 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/GreaterThanExpression.java#L6-L31","documentation":"Thrown by the custom GreaterThanExpression Pebble node when the '>' comparison fails. Like its '>=' counterpart, it first attempts string comparison, then delegates to OperatorUtils.gt. If the numeric comparison throws because the operands are incomparable types, the error is wrapped with this message.","triggerScenarios":"Using '>' between non-comparable types in a Pebble expression: '{{ mymap > 0 }}', '{{ null > 1 }}', '{{ somelist > 5 }}'. Also when one operand resolves to a boolean or complex type at runtime.","commonSituations":"Conditionals in flow templates that compare dynamically-typed outputs. A task output whose type varies between runs (sometimes a number, sometimes an object). Comparing dates represented as strings without first converting them to date types — note string comparison does work but lexicographic ordering may give unexpected results.","solutions":["Verify both sides of '>' resolve to mutually comparable types (both strings or both numbers).","Use a null-coalescing default: '{{ (outputs.task.value ?? 0) > threshold }}'.","Cast or parse the operand to a known numeric type before comparing."],"exampleFix":"{# before #}\n{% if outputs.task.value > limit %}\n\n{# after #}\n{% if (outputs.task.value ?? 0) > (limit ?? 0) %}","handlingStrategy":"validation","validationCode":"{# Default both sides to a numeric value before using > #}\n{% set left = (vars.value ?? 0) %}\n{% set right = (vars.limit ?? 0) %}\n{% if left > right %}...{% endif %}","typeGuard":"{# Guard against null or complex types before comparing #}\n{% set safe_val = outputs.task.value ?? 0 %}\n{% if safe_val is not null and safe_val is not iterable %}\n  {{ safe_val > 0 }}\n{% endif %}","tryCatchPattern":null,"preventionTips":["Use null-coalescing (??) to ensure both operands resolve to a number.","Verify the output type of upstream tasks used in '>' expressions.","Write unit tests for flow conditions that cover null and unexpected-type inputs."],"tags":["pebble","comparison","greater-than","type-mismatch"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}