apache/iceberg · error · IllegalArgumentException

Invalid operation type: %s

Error message

Invalid operation type: %s

What it means

Expression.Operation.fromString parses an operation name (e.g. "EQ", "IS_NULL") into an Operation enum. It throws IllegalArgumentException when the string is null or not a valid Operation enum constant name. Parsing is case-insensitive via toUpperCase(Locale.ROOT).

Source

Thrown at api/src/main/java/org/apache/iceberg/expressions/Expression.java:58

    IN,
    NOT_IN,
    NOT,
    AND,
    OR,
    STARTS_WITH,
    NOT_STARTS_WITH,
    COUNT,
    COUNT_NULL,
    COUNT_STAR,
    MAX,
    MIN;

    public static Operation fromString(String operationType) {
      Preconditions.checkArgument(null != operationType, "Invalid operation type: null");
      try {
        return Expression.Operation.valueOf(operationType.toUpperCase(Locale.ROOT));
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            String.format("Invalid operation type: %s", operationType), e);
      }
    }

    /** Returns the operation used when this is negated. */
    public Operation negate() {
      switch (this) {
        case IS_NULL:
          return Operation.NOT_NULL;
        case NOT_NULL:
          return Operation.IS_NULL;
        case IS_NAN:
          return Operation.NOT_NAN;
        case NOT_NAN:
          return Operation.IS_NAN;
        case LT:
          return Operation.GT_EQ;
        case LT_EQ:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use exact Operation enum constant names, e.g. EQ, NOT_EQ, IS_NULL, IN, NOT_IN, STARTS_WITH
  2. Call Expression.Operation.fromString with the upper-cased canonical name or rely on case-insensitivity but fix spelling
  3. Wrap parsing in try/catch for IllegalArgumentException when handling external input
  4. Print ExpressionUtil describe output to see valid operation names

Example fix

// before
Operation op = Operation.fromString("equals");
// after
Operation op = Operation.fromString("EQ"); // valid enum constant name
Defensive patterns

Strategy: try-catch

Validate before calling

boolean valid = operationType != null && Arrays.stream(Expression.Operation.values()).anyMatch(o -> o.name().equalsIgnoreCase(operationType));

Type guard

null

Try / catch

try { op = Expression.Operation.fromString(s); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Unknown predicate operation: " + s, e); }

Prevention

When it happens

Trigger: Passing a string that is not an Operation name to Operation.fromString — e.g. "equals" instead of "EQ", a lowercase-but-misspelled token like "equl", an alias such as "==" or "not_null" (underscore form is wrong), or null.

Common situations: Deserializing predicate JSON/avro where the operation field was produced by another tool with different naming, hand-written expression strings, or schema/avro files edited manually.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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