apache/druid · error · RE

Failed to convert array type

Error message

Failed to convert array type %s to expression type

What it means

Thrown when an explicitly typed array literal declares an ARRAY<TYPE> whose type name cannot be resolved to an ExpressionType (ExpressionType.fromString returned null). The declared array type is not a known Druid expression type.

Solutions

  1. Use a supported type keyword: LONG, DOUBLE, or STRING for typed array literals
  2. Remove the type annotation and use an untyped ARRAY literal
  3. Map SQL types to expression types (INT->LONG, VARCHAR->STRING) before generating the expression

Example fix

// before
ARRAY<INT>[1, 2, 3]
// after
ARRAY<LONG>[1, 2, 3]
Defensive patterns

Strategy: validation

Validate before calling

// Java: whitelist typed-array keywords before emitting
static final java.util.Set<String> ARRAY_TYPES = java.util.Set.of("LONG","DOUBLE","STRING");
boolean isSupportedArrayType(String t) {
  return ARRAY_TYPES.contains(t.trim().toUpperCase());
}

Prevention

When it happens

Trigger: Parsing an expression like ARRAY<WRONGTYPE>[...] where the token inside <> does not match a known type string (long, double, string, and their array forms).

Common situations: Typos in type names (ARRAY<INT> instead of ARRAY<LONG>); using SQL types like INT/VARCHAR in native expressions; copy-pasting SQL typed-array syntax into native expressions.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/math/expr/ExprListenerImpl.java:414

      if (ctx.numericElement(i).NULL() != null) {
        values[i] = null;
      } else if (ctx.numericElement(i).LONG() != null) {
        values[i] = Numbers.parseDoubleObject(ctx.numericElement(i).LONG().getText());
      } else if (ctx.numericElement(i).DOUBLE() != null) {
        values[i] = Numbers.parseDoubleObject(ctx.numericElement(i).DOUBLE().getText());
      } else {
        throw new RE("Failed to parse array element %s as a double", ctx.numericElement(i).getText());
      }
    }
    nodes.put(ctx, new ArrayExpr(ExpressionType.DOUBLE_ARRAY, values));
  }

  @Override
  public void exitExplicitArray(ExprParser.ExplicitArrayContext ctx)
  {
    ExpressionType type = ExpressionType.fromString(ctx.ARRAY_TYPE().getText());
    if (type == null) {
      throw new RE("Failed to convert array type %s to expression type", ctx.ARRAY_TYPE().getText());
    }
    Object[] values = new Object[ctx.literalElement().size()];
    for (int i = 0; i < values.length; i++) {
      if (ctx.literalElement(i).NULL() != null) {
        values[i] = null;
      } else {
        final ExprParser.LiteralElementContext elementContext = ctx.literalElement(i);
        // if value is a string, escape quoting
        final String toParse;
        if (elementContext.STRING() != null) {
          toParse = escapeStringLiteral(elementContext.STRING().getText());
        } else {
          toParse = elementContext.getText();
        }
        switch (type.getElementType().getType()) {
          case LONG:
            values[i] = Numbers.parseLongObject(toParse);
            break;

View on GitHub (pinned to 9b90983fd2)