apache/iceberg · error · ValidationException

Invalid value for conversion to type

Error message

Invalid value for conversion to type %s: %s (%s)

What it means

During bindLiteralOperation, the literal is converted to the bound term's type via literal().to(type). If the conversion returns null — meaning the value cannot be represented in the target type and is not the aboveMax/belowMin sentinel — binding fails with this ValidationException reporting the target type, the value, and its Java class.

Solutions

  1. Check the column type (schema.findType(name)) and construct the literal with the matching Java type before filtering
  2. Pre-validate the value fits the target type's range/precision (e.g. value fits int, decimal scale/precision match)
  3. Catch ValidationException around bind/filter and surface a user-friendly type error
  4. Fix the query to use a value compatible with the column type

Example fix

// before
Expression e = Expressions.equal("int_col", 99999999999L); // cannot convert to int
// after
Type t = schema.findType("int_col");
long v = 99999999999L;
Expression e = (t.typeId() == Type.TypeID.INTEGER)
    ? Expressions.equal("int_col", (int) v) // ensure it fits, or reject earlier
    : Expressions.equal("int_col", v);
Defensive patterns

Strategy: validation

Validate before calling

Type t = schema.findType(name);
// verify the literal's Java value is representable in t before building the predicate

Try / catch

try { table.filter(expr); } catch (ValidationException e) { /* report incompatible literal for column type to the user */ }

Prevention

When it happens

Trigger: Binding a predicate whose literal cannot be converted to the column type: e.g. comparing a long literal that overflows an int column in a way that produces no conversion, a string literal to a numeric column where conversion is undefined, or a decimal literal to an incompatible type.

Common situations: Engine-generated filters passing wrong-typed literals (string vs numeric); schema evolution changing column types so old hardcoded filter values no longer convert; user API queries filtering a long column with a value beyond the column's precision.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at api/src/main/java/org/apache/iceberg/expressions/UnboundPredicate.java:182

  }

  private boolean floatingType(Type.TypeID typeID) {
    return Type.TypeID.DOUBLE.equals(typeID) || Type.TypeID.FLOAT.equals(typeID);
  }

  private Expression bindLiteralOperation(BoundTerm<T> boundTerm) {
    if (op() == Operation.STARTS_WITH || op() == Operation.NOT_STARTS_WITH) {
      ValidationException.check(
          boundTerm.type().equals(Types.StringType.get()),
          "Term for STARTS_WITH or NOT_STARTS_WITH must produce a string: %s: %s",
          boundTerm,
          boundTerm.type());
    }

    Literal<T> lit = literal().to(boundTerm.type());

    if (lit == null) {
      throw new ValidationException(
          "Invalid value for conversion to type %s: %s (%s)",
          boundTerm.type(), literal().value(), literal().value().getClass().getName());

    } else if (lit == Literals.aboveMax()) {
      switch (op()) {
        case LT:
        case LT_EQ:
        case NOT_EQ:
          return Expressions.alwaysTrue();
        case GT:
        case GT_EQ:
        case EQ:
          return Expressions.alwaysFalse();
      }
    } else if (lit == Literals.belowMin()) {
      switch (op()) {
        case GT:
        case GT_EQ:

View on GitHub (pinned to 86d9c8fc54)