apache/druid · error · IAE
Cannot create type [ ]
Error message
Cannot create type [%s]
What it means
ExprEval.ofType converts a deserialized value into an ExprEval of the requested type. For a null-typed or otherwise unhandled ExpressionType it falls through the switch and throws IAE 'Cannot create type'. Arrays and non-array mismatches are handled by bestEffortOf+castTo, so this only fires for types entirely outside the supported set.
Solutions
- Use a supported ExpressionType (LONG, LONG_ARRAY, DOUBLE, DOUBLE_ARRAY, STRING, STRING_ARRAY, COMPLEX, etc.) when calling ofType
- If the input value may mismatch, call ExprEval.bestEffortOf(value).castTo(type) yourself instead of ofType
- Check the serialized type signature producing the value; fix the writer side
Example fix
// before ExprEval.ofType(ExpressionType.fromTypeFull(NullType.NAME), value); // after ExprEval.bestEffortOf(value).castTo(ExpressionType.STRING);
Defensive patterns
Strategy: type-guard
Validate before calling
switch (type.getFactory()) {
case LONG: case LONG_ARRAY: case DOUBLE: case DOUBLE_ARRAY:
case STRING: case STRING_ARRAY: case COMPLEX: /* ok */ break;
default: throw new IllegalArgumentException("unsupported type " + type);
} Try / catch
try {
eval = ExprEval.ofType(type, value);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Cannot create type")) {
eval = ExprEval.bestEffortOf(value).castTo(ExpressionType.STRING);
} else { throw e; }
} Prevention
- Only pass ExpressionType values from the standard registry
- Prefer bestEffortOf().castTo() for uncertain inputs
- Guard against version skew on newly added types
When it happens
Trigger: Calling ExprEval.ofType(type, value) with an ExpressionType whose registry kind is not handled (e.g. a null-typed type or a newly added type not yet supported).
Common situations: Deserializing values with a corrupted or unexpected type signature; custom code constructing ExpressionType instances outside the standard registry; version skew where a newer type is read by older code.
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 add / to a Spectator Histogram
- Cannot cast [ ] to [ ] (Types.InvalidCastException from…
- Cannot deserialize type
- Cannot implicitly cast
- needs a LONG as its second argument but got
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/a47efb215807ca76.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/math/expr/ExprEval.java:621
}
return ofArray(type, array);
}
if (value instanceof Object[]) {
Object[] inputArray = (Object[]) value;
Object[] array = new Object[inputArray.length];
int i = 0;
for (Object o : inputArray) {
array[i++] = ExprEval.ofType(elementType, o).value();
}
return ofArray(type, array);
}
// in a better world, we might get an object that matches the type signature for arrays and could do a switch
// statement here, but this is not that world yet, and things that are array typed might also be non-arrays,
// e.g. we might get a String instead of String[], so just fallback to bestEffortOf
return bestEffortOf(value).castTo(type);
}
throw new IAE("Cannot create type [%s]", type);
}
@Nullable
public static Number computeNumber(@Nullable String value)
{
if (value == null) {
return null;
}
if (Evals.asBoolean(value)) {
return 1.0;
}
if (value.equalsIgnoreCase("false")) {
return 0.0;
}
Number rv;
Long v = GuavaUtils.tryParseLong(value);
// Do NOT use ternary operator here, because it makes Java to convert Long to Double
if (v != null) {View on GitHub (pinned to 9b90983fd2)