apache/seatunnel · error · org.apache.seatunnel.api.configuration.util.OptionValidationException

Cannot compare null values in numeric comparison…

Error message

Cannot compare null values in numeric comparison: leftPresent=%s, rightPresent=%s

What it means

Thrown from ConditionEvaluators.compareNumbers when a numeric condition operator (e.g. GT, LT, EQ) is evaluated and one side of the comparison is null. At its throw site it means the conditional option referenced a value that is absent (missing key or null), so no ordering comparison is defined; it is a validation guard against ambiguous null ordering, not a numeric-format error. The message reports which side was present via booleans.

Solutions

  1. Ensure the config option the condition compares against is defined and non-null before the condition is evaluated
  2. Use a condition operator that tolerates absence, or guard the conditional option with a presence check (e.g. option required=true or a default value)
  3. Provide a sensible default for the option via Option.defaultValue so the left/right operand is never null
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/configuration/util/ConditionEvaluators.java:187 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/1e1c2f55c9c8f9b4. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/configuration/util/ConditionEvaluators.java:187

                ConditionOperator.EXTENSION,
                (v, c, cfg) -> {
                    ConditionExtension<Object> ext = (ConditionExtension<Object>) c.getExtension();
                    return ext.evaluate(cfg, v);
                });

        for (ConditionOperator op : ConditionOperator.values()) {
            if (!m.containsKey(op)) {
                throw new IllegalStateException(
                        "Missing evaluator for ConditionOperator." + op.name());
            }
        }
        return Collections.unmodifiableMap(m);
    }

    @SuppressWarnings({"rawtypes"})
    static int compareNumbers(Object a, Object b) {
        if (a == null || b == null) {
            throw new OptionValidationException(
                    "Cannot compare null values in numeric comparison: leftPresent=%s, rightPresent=%s",
                    a != null, b != null);
        }
        if (a instanceof Number && b instanceof Number) {
            return compareNumberValues((Number) a, (Number) b);
        }
        if (a instanceof Comparable && b instanceof Comparable) {
            return ((Comparable) a).compareTo(b);
        }
        throw new OptionValidationException(
                "Cannot compare values of type %s and %s",
                a.getClass().getSimpleName(), b.getClass().getSimpleName());
    }

    private static int compareNumberValues(Number a, Number b) {
        if (a instanceof BigDecimal || b instanceof BigDecimal) {
            BigDecimal bdA =
                    a instanceof BigDecimal ? (BigDecimal) a : new BigDecimal(a.toString());

View on GitHub (pinned to cf67b549a7)