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
- Ensure the config option the condition compares against is defined and non-null before the condition is evaluated
- 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)
- 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)