apache/iceberg · error · UnsupportedOperationException

Cannot change the type of AboveMax

Error message

Cannot change the type of AboveMax

What it means

AboveMax sentinel literals cannot be retyped: to(Type) throws UnsupportedOperationException because there is no concrete value to convert or overflow-check again. AboveMax already represents 'above every value of any type', so type conversion is meaningless.

Source

Thrown at api/src/main/java/org/apache/iceberg/expressions/Literals.java:188

    @SuppressWarnings("unchecked")
    public Comparator<C> comparator() {
      return (Comparator<C>) CMP;
    }
  }

  static class AboveMax<T> implements Literal<T> {
    private static final AboveMax INSTANCE = new AboveMax();

    private AboveMax() {}

    @Override
    public T value() {
      throw new UnsupportedOperationException("AboveMax has no value");
    }

    @Override
    public <X> Literal<X> to(Type type) {
      throw new UnsupportedOperationException("Cannot change the type of AboveMax");
    }

    @Override
    public Comparator<T> comparator() {
      throw new UnsupportedOperationException("AboveMax has no comparator");
    }

    @Override
    public String toString() {
      return "aboveMax";
    }
  }

  static class BelowMin<T> implements Literal<T> {
    private static final BelowMin INSTANCE = new BelowMin();

    private BelowMin() {}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Skip conversion when the literal is already AboveMax/BelowMin (instanceof check) and pass the sentinel through unchanged
  2. Guard generic to() calls with a type check for sentinel literals
  3. Restructure conversion code so overflow to AboveMax terminates the conversion pipeline

Example fix

// before
Literal<T> retyped = (Literal<T>) lit.to(targetType); // throws for AboveMax
// after
Literal<?> retyped = (lit instanceof Literals.AboveMax || lit instanceof Literals.BelowMin)
    ? lit : lit.to(targetType);
Defensive patterns

Strategy: type-guard

Validate before calling

if (lit instanceof Literals.AboveMax || lit instanceof Literals.BelowMin) {
  // pass sentinel through; do not call to(Type)
}

Type guard

static boolean retypable(Literal<?> lit) {
  return !(lit instanceof Literals.AboveMax) && !(lit instanceof Literals.BelowMin);
}

Try / catch

Literal<?> out;
try {
  out = lit.to(targetType);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("Cannot change the type of AboveMax")) {
    out = lit; // sentinel is type-independent
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling to(Type) on Literals.aboveMax() or on a literal known to be an AboveMax sentinel — e.g. generic code that calls lit.to(expectedType) on every literal in an expression when rewriting predicates for a column's type.

Common situations: Generic predicate-rewriting code (e.g. adapting filters to projected/partition types) blindly converting literals; chained conversions where a first to() produced AboveMax and a second conversion is attempted.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/c06f6d1e2279e74b. Report an issue: GitHub.