apache/druid · error · ExpressionValidationException
Invalid type [%s]
Error message
Invalid type [%s]
What it means
The expression-language CAST(value, type) function parses its second argument as an ExpressionType via fromString (uppercased). If the string is not a registered type name (LONG, DOUBLE, FLOAT, STRING, ARRAY<...>, COMPLEX<...>), parsing throws IllegalArgumentException which is converted into this validation error.
Source
Thrown at processing/src/main/java/org/apache/druid/math/expr/Function.java:2002
}
class CastFunc extends BivariateFunction
{
@Override
public String name()
{
return "cast";
}
@Override
protected ExprEval eval(ExprEval x, ExprEval y)
{
ExpressionType castTo;
try {
castTo = ExpressionType.fromString(StringUtils.toUpperCase(y.asString()));
}
catch (IllegalArgumentException e) {
throw validationFailed("Invalid type [%s]", y.asString());
}
if (x.value() == null) {
return ExprEval.ofType(castTo, null);
} else {
return x.castTo(castTo);
}
}
@Override
public Set<Expr> getScalarInputs(List<Expr> args)
{
if (args.get(1).isLiteral()) {
ExpressionType castTo = ExpressionType.fromString(
StringUtils.toUpperCase(args.get(1).getLiteralValue().toString())
);
switch (castTo.getType()) {
case ARRAY:
return Collections.emptySet();View on GitHub (pinned to 9b90983fd2)
Solutions
- Use expression type names: 'LONG', 'DOUBLE', 'FLOAT', 'STRING', 'ARRAY<STRING>', etc.
- Replace SQL-only names: INT -> LONG, BIGINT -> LONG, VARCHAR -> STRING
- Validate the type string against ExpressionType.fromString before building the query dynamically
- Check the native query JSON expression, not the SQL text — the SQL layer rewrites casts automatically
Example fix
// before: CAST(x, 'INT') -> Invalid type [INT] // after: CAST(x, 'LONG')
Defensive patterns
Strategy: validation
Validate before calling
Set<String> valid = Set.of("LONG","FLOAT","DOUBLE","STRING","ARRAY<STRING>","ARRAY<LONG>","ARRAY<DOUBLE>");
if (!valid.contains(typeStr.toUpperCase(Locale.ROOT))) {
throw new IllegalArgumentException("unknown expression type " + typeStr);
} Type guard
static boolean isValidExprTypeName(String s) {
try { ExpressionType.fromString(StringUtils.toUpperCase(s)); return true; }
catch (IllegalArgumentException e) { return false; }
} Prevention
- Use expression type names, not SQL type names (INT->LONG, VARCHAR->STRING)
- Prefer SQL-level CAST which the planner rewrites correctly
- Test generated native expressions before production
When it happens
Trigger: Calling CAST(x, 'INT') or CAST(x, 'VARCHAR') — SQL type names are not valid expression-language type names — or any misspelled type string inside a native expression.
Common situations: Writing SQL type names inside native-expression CAST(); typos like 'STRNG'; hand-rolled native queries generated from SQL dialect conventions (the SQL planner rewrites casts, raw expressions do not).
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
- Cannot cast [%s] to [%s] (Types.InvalidCastException from in
- Unsupported unknown value type
- Unsupported value type[%s]
- Unsupported expression type[%s]
- Cannot implicitly cast [%s] to [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/72bfa52c158e07be.
Report an issue: GitHub.