apache/druid · error · ExpressionValidationException

second argument must be a a scalar type but got %s instead

Error message

second argument must be a a scalar type but got %s instead

What it means

Thrown by Druid's array_offset-like expression function when the second argument (the element to search / index lookup value) has a non-scalar type, i.e. it is itself an array or complex type. The search key must be a LONG, STRING, DOUBLE, etc. — never an array.

Source

Thrown at processing/src/main/java/org/apache/druid/math/expr/Function.java:3741

    @Override
    ExprEval doApply(ExprEval arrayExpr, ExprEval scalarExpr)
    {
      final Object[] array = arrayExpr.asArray();

      switch (scalarExpr.type().getType()) {
        case STRING:
        case LONG:
        case DOUBLE:
          int index = -1;
          for (int i = 0; i < array.length; i++) {
            if (Objects.equals(array[i], scalarExpr.value())) {
              index = i;
              break;
            }
          }
          return index < 0 ? ExprEval.ofLong(null) : ExprEval.ofLong(index);
        default:
          throw validationFailed(
              "second argument must be a a scalar type but got %s instead",
              scalarExpr.type()
          );
      }
    }
  }

  class ArrayOrdinalOfFunction extends ArrayScalarFunction
  {
    @Override
    public String name()
    {
      return "array_ordinal_of";
    }

    @Nullable
    @Override
    public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Pass a scalar value (literal or scalar column) as the second argument, e.g. array_offset(arr, 'target').
  2. If you intended an index lookup, use array_offset(arr, 0) with a numeric index.
  3. Unwrap the nested array first (e.g. with array_offset on the outer array) before using the result as the search key.
  4. Verify column types in the schema; cast the argument to VARCHAR/BIGINT if it is a complex type mishap.

Example fix

// before
array_offset(arr, array('a','b'))
// after
array_offset(arr, 'a')
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure search key is scalar in SQL
CASE WHEN CARDINALITY(key) > 0 THEN ... ELSE NULL END -- or just never pass arrays

Type guard

// reject array-typed arguments before calling
if (isArrayType(argType)) throw new IllegalArgumentException("search key must be scalar");

Prevention

When it happens

Trigger: Evaluating array_offset(arr, nestedArray) where the second argument is an ARRAY ExprType, e.g. passing another array column or an array() construction as the search value.

Common situations: Confusing array_offset with functions that take an index; accidentally passing an array literal instead of a scalar; schema changes turning a formerly scalar column into an array.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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