apache/druid · error · RE

Invalid expression: %s; %s used as both scalar and array var

Error message

Invalid expression: %s; %s used as both scalar and array variables

What it means

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.

Source

Thrown at processing/src/main/java/org/apache/druid/math/expr/Parser.java:626

        newFn = new ApplyFunction.CartesianFoldFunction();
        newExpr = new ApplyFunctionExpr(newFn, newFn.name(), newFoldLambda, newFoldArgs);
        break;
      default:
        throw new RE("Unable to transform apply function:[%s]", expr.function.name());
    }

    return newExpr;
  }

  /**
   * Validate that an expression uses input bindings in a type consistent manner.
   */
  public static void validateExpr(Expr expression, Expr.BindingAnalysis bindingAnalysis)
  {
    final Set<String> conflicted =
        Sets.intersection(bindingAnalysis.getScalarBindings(), bindingAnalysis.getArrayBindings());
    if (!conflicted.isEmpty()) {
      throw new RE("Invalid expression: %s; %s used as both scalar and array variables", expression, conflicted);
    }
  }

}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Rename one of the conflicting variables so scalar and array uses have distinct identifiers.
  2. If the column is an array, use array accessor functions consistently instead of scalar arithmetic on it.
  3. In lambdas, alias the array argument to a different identifier before scalar use.

Example fix

// before
"x + ARRAY_OFFSET(x, 0)" // x used as scalar and array
// after
"x + ARRAY_OFFSET(arr_x, 0)" // distinct identifiers
Defensive patterns

Strategy: validation

Validate before calling

Expr.BindingAnalysis a = expr.analyzeInputs();
Set<String> conflict = Sets.intersection(a.getScalarBindings(), a.getArrayBindings());
if (!conflict.isEmpty()) throw new IllegalArgumentException("ambiguous identifiers: " + conflict);

Try / catch

try { Parser.validateExpr(expr, analysis); } catch (RuntimeException e) { if (e.getMessage().contains("both scalar and array")) { /* prompt rename */ } }

Prevention

When it happens

Trigger: 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)".

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/d21be98158fae1a5. Report an issue: GitHub.