{"record":{"id":"7f781880523941dc","repo":"apache/druid","slug":"argument-s-should-be-an-identifier-expression-us","errorCode":null,"errorMessage":"argument %s should be an identifier expression. Use array() instead","messagePattern":"argument (.+?) should be an identifier expression\\. Use array\\(\\) instead","errorType":"validation","errorClass":"ExpressionValidationException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Function.java","lineNumber":3318,"sourceCode":"    public String name()\n    {\n      return \"mv_to_array\";\n    }\n\n    @Override\n    public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)\n    {\n      return args.get(0).eval(bindings).castTo(ExpressionType.STRING_ARRAY);\n    }\n\n    @Override\n    public void validateArguments(List<Expr> args)\n    {\n      validationHelperCheckArgumentCount(args, 1);\n      IdentifierExpr expr = args.get(0).getIdentifierExprIfIdentifierExpr();\n\n      if (expr == null) {\n        throw validationFailed(\n            \"argument %s should be an identifier expression. Use array() instead\",\n            args.get(0).toString()\n        );\n      }\n    }\n\n    @Nullable\n    @Override\n    public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)\n    {\n      return ExpressionType.STRING_ARRAY;\n    }\n\n    @Override\n    public boolean hasArrayInputs()\n    {\n      return true;\n    }","sourceCodeStart":3300,"sourceCodeEnd":3336,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Function.java#L3300-L3336","documentation":"Thrown during argument validation when a Druid expression function requires its first (only) argument to be an identifier expression — i.e. a bare column reference — but receives an arbitrary expression. The message hints that if an array value was intended, the array() constructor should be used instead.","triggerScenarios":"Calling the function with a computed expression, literal, or nested function call as the first argument, e.g. f(COALESCE(col, 'x')) or f('literal'), instead of a plain column name like f(col).","commonSituations":"Rewriting queries where the original wrapped the column in a function; users trying to pass an inline array literal with legacy syntax instead of array(1,2,3); query builders that auto-wrap columns.","solutions":["Pass a bare column identifier as the first argument, e.g. f(myColumn).","If you meant to supply an array value, use the array() constructor: f(array(1, 2, 3)) as appropriate for the function.","Materialize the intermediate expression into a new column (e.g. via a subquery/ingestion expression) and reference that column.","Check the function's documentation to confirm it operates on identifiers (e.g. for special planning/index handling)."],"exampleFix":"// before\nsome_fn(CONCAT(col, '_x'))\n// after\nsome_fn(col)","handlingStrategy":"validation","validationCode":"// only pass bare column references\nassert (!(arg instanceof Expr)) || arg instanceof Column; // API users: pass \"col\", not expressions","typeGuard":"// ensure first arg is a plain identifier, not a call or literal\nif (arg.startsWith(\"(\") || arg.contains(\"(\")) reject();","tryCatchPattern":null,"preventionTips":["Pass plain column names to identifier-requiring functions","Use array(...) for array literals","Materialize intermediate expressions in a subquery first"],"tags":["druid","expressions","argument-validation"],"backgroundTag":"invalid-argument","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}