apache/druid · error · Types.IncompatibleTypeException

Cannot implicitly cast [%s] to [%s]

Error message

Cannot implicitly cast [%s] to [%s]

What it means

ExpressionTypeConversion.operator() computes the common type for the two operands of an expression operator. When either operand is a COMPLEX (non-nested-data) expression type, the two complex types must be identical; mixing two different complex types (e.g. two different extension complex types) in one operator is rejected with Types.IncompatibleTypeException, surfaced as 'Cannot implicitly cast [x] to [y]'.

Source

Thrown at processing/src/main/java/org/apache/druid/math/expr/ExpressionTypeConversion.java:104

  {
    if (type == null) {
      return other;
    }
    if (other == null) {
      return type;
    }
    if (type.isArray() || other.isArray()) {
      return leastRestrictiveType(type, other);
    }
    if (type.is(ExprType.COMPLEX) || other.is(ExprType.COMPLEX)) {
      if (type.getComplexTypeName() == null) {
        return other;
      }
      if (other.getComplexTypeName() == null) {
        return type;
      }
      if (!Objects.equals(type, other)) {
        throw new Types.IncompatibleTypeException(type, other);
      }
      return type;
    }
    // if both arguments are a string, type becomes a string
    if (type.is(ExprType.STRING) && other.is(ExprType.STRING)) {
      return ExpressionType.STRING;
    }

    // otherwise a decimal or integer number
    return numeric(type, other);
  }

  /**
   * Given 2 'input' types, choose the most appropriate combined type, if possible
   *
   * arrays must be the same type
   * if either type is {@link ExprType#STRING}, the output type will be preserved as string
   * if both types are {@link ExprType#LONG}, the output type will be preserved as long, otherwise

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Don't apply operators directly to complex columns; extract a primitive first (e.g. use the extension's accessor/extractor functions to get a LONG/DOUBLE/STRING).
  2. Ensure both operands resolve to the same complex type name, or cast one side appropriately.
  3. Check the RowSignature typing — a mis-declared column type can make a plain value appear COMPLEX.
  4. Catch Types.IncompatibleTypeException during query validation and return a clear 'cannot combine types' message to the user.

Example fix

// before
"complexColA + complexColB"
// after
"extractValue(complexColA) + extractValue(complexColB)" // extract primitives before operators
Defensive patterns

Strategy: validation

Validate before calling

if (type != null && other != null && type.is(ExprType.COMPLEX) && other.is(ExprType.COMPLEX)
    && !Objects.equals(type, other)) {
  throw new IllegalStateException("Cannot combine complex types " + type + " and " + other);
}

Type guard

boolean operatorSafe(ExpressionType a, ExpressionType b) {
  return !(a.is(ExprType.COMPLEX) && b.is(ExprType.COMPLEX) && !a.equals(b));
}

Try / catch

try {
  ExpressionType t = ExpressionTypeConversion.operator(a, b);
} catch (Types.IncompatibleTypeException e) {
  throw new QueryPlanningException("Operands have incompatible types: " + e.getMessage());
}

Prevention

When it happens

Trigger: Using an arithmetic/comparison operator between two different COMPLEX expression types, e.g. expressions over two different complex columns (different complex type names) combined with +, -, *, ==, etc.

Common situations: Combining columns backed by different Druid extensions (e.g. two distinct sketch/complex serializers) in one expression; mistyping a column so a complex value is treated as numeric; writing native expressions in filters/select operators over complex columns.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1fbcd850dc879672. Report an issue: GitHub.