{"record":{"id":"d21be98158fae1a5","repo":"apache/druid","slug":"invalid-expression-s-s-used-as-both-scalar-and","errorCode":null,"errorMessage":"Invalid expression: %s; %s used as both scalar and array variables","messagePattern":"Invalid expression: (.+?); (.+?) used as both scalar and array variables","errorType":"validation","errorClass":"RE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Parser.java","lineNumber":626,"sourceCode":"        newFn = new ApplyFunction.CartesianFoldFunction();\n        newExpr = new ApplyFunctionExpr(newFn, newFn.name(), newFoldLambda, newFoldArgs);\n        break;\n      default:\n        throw new RE(\"Unable to transform apply function:[%s]\", expr.function.name());\n    }\n\n    return newExpr;\n  }\n\n  /**\n   * Validate that an expression uses input bindings in a type consistent manner.\n   */\n  public static void validateExpr(Expr expression, Expr.BindingAnalysis bindingAnalysis)\n  {\n    final Set<String> conflicted =\n        Sets.intersection(bindingAnalysis.getScalarBindings(), bindingAnalysis.getArrayBindings());\n    if (!conflicted.isEmpty()) {\n      throw new RE(\"Invalid expression: %s; %s used as both scalar and array variables\", expression, conflicted);\n    }\n  }\n\n}\n","sourceCodeStart":608,"sourceCodeEnd":631,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Parser.java#L608-L631","documentation":"Parser.validateExpr checks that a variable identifier is never used with two different binding kinds in one expression. If binding analysis reports the same identifier in both scalarBindings and arrayBindings, the expression is ambiguous/invalid and RE 'Invalid expression: %s; %s used as both scalar and array variables' is thrown naming the conflicting identifiers.","triggerScenarios":"Calling Parser.validateExpr(expr, expr.analyzeInputs(...)) with an expression where one identifier appears both as a scalar (e.g. \"x + 1\") and as an array operand (e.g. \"ARRAY_OFFSET(x, 1)\") — for example \"x + ARRAY_OFFSET(x, 0)\".","commonSituations":"Lambda/apply expressions where a parameter is used both scalarly and as an array; copy-pasted expressions mixing array functions and scalar math on the same column; writing reduction/fold lambdas that reuse the accumulator name for array input.","solutions":["Rename one of the conflicting variables so scalar and array uses have distinct identifiers.","If the column is an array, use array accessor functions consistently instead of scalar arithmetic on it.","In lambdas, alias the array argument to a different identifier before scalar use."],"exampleFix":"// before\n\"x + ARRAY_OFFSET(x, 0)\" // x used as scalar and array\n// after\n\"x + ARRAY_OFFSET(arr_x, 0)\" // distinct identifiers","handlingStrategy":"validation","validationCode":"Expr.BindingAnalysis a = expr.analyzeInputs();\nSet<String> conflict = Sets.intersection(a.getScalarBindings(), a.getArrayBindings());\nif (!conflict.isEmpty()) throw new IllegalArgumentException(\"ambiguous identifiers: \" + conflict);","typeGuard":null,"tryCatchPattern":"try { Parser.validateExpr(expr, analysis); } catch (RuntimeException e) { if (e.getMessage().contains(\"both scalar and array\")) { /* prompt rename */ } }","preventionTips":["Never reuse one identifier as both scalar and array in the same expression","In lambdas, give array parameters distinct names","Run validateExpr in tests for all expression templates"],"tags":["expression","validation","binding-conflict","druid"],"backgroundTag":"schema-validation-failed","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"}