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

  1. Verify both sides of '>' resolve to mutually comparable types (both strings or both numbers).
  2. Use a null-coalescing default: '{{ (outputs.task.value ?? 0) > threshold }}'.
  3. 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

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


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/5dd7694c008ac0d1. Report an issue: GitHub.