{"record":{"id":"72bfa52c158e07be","repo":"apache/druid","slug":"invalid-type-s","errorCode":null,"errorMessage":"Invalid type [%s]","messagePattern":"Invalid type \\[(.+?)\\]","errorType":"validation","errorClass":"ExpressionValidationException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Function.java","lineNumber":2002,"sourceCode":"  }\n\n  class CastFunc extends BivariateFunction\n  {\n    @Override\n    public String name()\n    {\n      return \"cast\";\n    }\n\n    @Override\n    protected ExprEval eval(ExprEval x, ExprEval y)\n    {\n      ExpressionType castTo;\n      try {\n        castTo = ExpressionType.fromString(StringUtils.toUpperCase(y.asString()));\n      }\n      catch (IllegalArgumentException e) {\n        throw validationFailed(\"Invalid type [%s]\", y.asString());\n      }\n      if (x.value() == null) {\n        return ExprEval.ofType(castTo, null);\n      } else {\n        return x.castTo(castTo);\n      }\n    }\n\n    @Override\n    public Set<Expr> getScalarInputs(List<Expr> args)\n    {\n      if (args.get(1).isLiteral()) {\n        ExpressionType castTo = ExpressionType.fromString(\n            StringUtils.toUpperCase(args.get(1).getLiteralValue().toString())\n        );\n        switch (castTo.getType()) {\n          case ARRAY:\n            return Collections.emptySet();","sourceCodeStart":1984,"sourceCodeEnd":2020,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Function.java#L1984-L2020","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before: CAST(x, 'INT') -> Invalid type [INT]\n// after: CAST(x, 'LONG')","handlingStrategy":"validation","validationCode":"Set<String> valid = Set.of(\"LONG\",\"FLOAT\",\"DOUBLE\",\"STRING\",\"ARRAY<STRING>\",\"ARRAY<LONG>\",\"ARRAY<DOUBLE>\");\nif (!valid.contains(typeStr.toUpperCase(Locale.ROOT))) {\n  throw new IllegalArgumentException(\"unknown expression type \" + typeStr);\n}","typeGuard":"static boolean isValidExprTypeName(String s) {\n  try { ExpressionType.fromString(StringUtils.toUpperCase(s)); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["druid","expressions","cast","invalid-type"],"backgroundTag":"invalid-enum-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}