kestra-io/kestra · error · PebbleException
Could not perform greater than comparison
Error message
Could not perform greater than comparison
What it means
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.
Source
Thrown at core/src/main/java/io/kestra/core/runners/pebble/expression/GreaterThanExpression.java:24
import io.pebbletemplates.pebble.template.PebbleTemplateImpl;
import io.pebbletemplates.pebble.utils.OperatorUtils;
public class GreaterThanExpression extends BinaryExpression<Boolean> {
@Override
public Boolean evaluate(PebbleTemplateImpl self, EvaluationContextImpl context) {
Object left = this.getLeftExpression().evaluate(self, context);
Object right = this.getRightExpression().evaluate(self, context);
// add support for string comparison
if (left instanceof String sLeft && right instanceof String sRight) {
return sLeft.compareTo(sRight) > 0;
}
// default implementation from io.pebbletemplates.pebble.node.expression.GreaterThanExpression
try {
return OperatorUtils.gt(left, right);
} catch (Exception ex) {
throw new PebbleException(
ex, "Could not perform greater than comparison", this.getLineNumber(), self
.getName()
);
}
}
}
View on GitHub (pinned to 823fada927)
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.
Example fix
{# before #}
{% if outputs.task.value > limit %}
{# after #}
{% if (outputs.task.value ?? 0) > (limit ?? 0) %} Defensive patterns
Strategy: validation
Validate before calling
{# Default both sides to a numeric value before using > #}
{% set left = (vars.value ?? 0) %}
{% set right = (vars.limit ?? 0) %}
{% if left > right %}...{% endif %} Type guard
{# Guard against null or complex types before comparing #}
{% set safe_val = outputs.task.value ?? 0 %}
{% if safe_val is not null and safe_val is not iterable %}
{{ safe_val > 0 }}
{% endif %} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not perform greater than or equals comparison
- Could not perform less than or equals comparison
- Could not perform less than comparisonPebb
- Cannot concat {} with {}
- 'chunk' filter can only be applied to List. Actual type was:
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/5dd7694c008ac0d1.
Report an issue: GitHub.