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, otherwiseView on GitHub (pinned to 9b90983fd2)
Solutions
- 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).
- Ensure both operands resolve to the same complex type name, or cast one side appropriately.
- Check the RowSignature typing — a mis-declared column type can make a plain value appear COMPLEX.
- 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
- Extract primitives from complex columns before applying operators
- Never mix different complex extension types in one expression
- Validate RowSignature types during query planning
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
- Cannot find strategy for type [%s]
- first argument must be a valid COMPLEX type name, got unknow
- second argument must be a base64 encoded STRING value but go
- Cannot cast [%s] to [%s] (Types.InvalidCastException from in
- second argument should be STRING but got %s instead
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1fbcd850dc879672.
Report an issue: GitHub.