kestra-io/kestra · error · PebbleException

Could not perform greater than or equals comparison

Error message

Could not perform greater than or equals comparison

What it means

Thrown by the custom GreaterThanEqualsExpression Pebble node when the '>=' comparison cannot be performed. The expression first tries native string comparison (if both sides are strings), then delegates to Pebble's OperatorUtils.gte for numeric comparisons. If gte throws — typically because the operands are incomparable types — the exception is wrapped and rethrown with this message.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/expression/GreaterThanEqualsExpression.java:24

import io.pebbletemplates.pebble.template.PebbleTemplateImpl;
import io.pebbletemplates.pebble.utils.OperatorUtils;

public class GreaterThanEqualsExpression 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.gte(left, right);
        } catch (Exception ex) {
            throw new PebbleException(
                ex, "Could not perform greater than or equals comparison", this.getLineNumber(), self
                    .getName()
            );
        }
    }
}

View on GitHub (pinned to 823fada927)

Solutions

  1. Ensure both operands of '>=' are either both strings or both numbers.
  2. Guard against null with a default: '{{ (vars.value ?? 0) >= 5 }}'.
  3. Add a type-check or cast before comparison to confirm the operand is numeric.

Example fix

{# before #}
{% if outputs.task.value >= 10 %}

{# after — guard null + ensure numeric #}
{% if (outputs.task.value ?? 0) >= 10 %}
Defensive patterns

Strategy: validation

Validate before calling

{# Default both sides to a numeric value before using >= #}
{% set left = (vars.metric ?? 0) %}
{% set right = (vars.threshold ?? 0) %}
{% if left >= right %}...{% endif %}

Type guard

{# Pebble does not have a native 'is number' test, but you can guard with a default #}
{% set safe_val = vars.value ?? 0 %}
{% if safe_val is not null and safe_val is iterable %}
  {# value is a collection — do not compare with >= #}
{% else %}
  {{ safe_val >= 10 }}
{% endif %}

Prevention

When it happens

Trigger: Using the '>=' operator in a Pebble template between operands that are neither both strings nor mutually comparable numbers: '{{ somelist >= 5 }}', '{{ null >= 3 }}', or '{{ mymap >= "abc" }}'. Also when one side is null and the other is a non-string.

Common situations: Comparing a variable that resolves to null, a list, or a map against a number or string. Flow conditions using '>=' on outputs whose type is not guaranteed (e.g., comparing a task output that might be a JSON object). Version upgrades where an output type changed from scalar to complex.

Related errors


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