apache/druid · error · BadQueryContextException

Expected key [%s] to be of type [%s], but got [%s]

Error message

Expected key [%s] to be of type [%s], but got [%s]

What it means

QueryContexts.getAsEnum only converts String and Boolean context values to enums; any other type (number, map, list) reaches the fall-through badTypeException. Druid throws this BadQueryContextException because the context value's type cannot possibly represent an enum constant, so it aborts query submission with an explicit expected-vs-actual type message.

Source

Thrown at processing/src/main/java/org/apache/druid/query/QueryContexts.java:581

        return Enum.valueOf(clazz, StringUtils.toUpperCase((String) value));
      } else if (value instanceof Boolean) {
        return Enum.valueOf(clazz, StringUtils.toUpperCase(String.valueOf(value)));
      }
    }
    catch (IllegalArgumentException e) {
      throw badValueException(
          key,
          StringUtils.format(
              "referring to one of the values [%s] of enum [%s]",
              Arrays.stream(clazz.getEnumConstants()).map(Enum::name).collect(
                  Collectors.joining(",")),
              clazz.getSimpleName()
          ),
          value
      );
    }

    throw badTypeException(
        key,
        StringUtils.format("of type [%s]", clazz.getSimpleName()),
        value
    );
  }

  public static BadQueryContextException badValueException(
      final String key,
      final String expected,
      final Object actual
  )
  {
    return new BadQueryContextException(
        StringUtils.format(
            "Expected key [%s] to be %s, but got [%s]",
            key,
            expected,
            actual

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Quote the context value as a string matching an enum constant name, e.g. "vectorize": "true" instead of 1.
  2. Use QueryContexts's typed setters or ensure your query builder serializes the field as a JSON string.
  3. Change boolean-like numbers to real JSON booleans or enum constant names before submitting.

Example fix

// before
context.put("vectorize", 1);
// after
context.put("vectorize", "true");
Defensive patterns

Strategy: type-guard

Validate before calling

// Java
if (!(value instanceof String) && !(value instanceof Boolean)) {
  throw new IllegalArgumentException("context enum values must be String or Boolean");
}

Type guard

static boolean isEnumConvertible(Object v) {
  return v instanceof String || v instanceof Boolean;
}

Try / catch

try {
  QueryContexts.getEnum(context, key, MyEnum.class);
} catch (BadQueryContextException e) {
  log.error("Context key {} has wrong type: {}", key, e.getMessage());
}

Prevention

When it happens

Trigger: Passing a non-string/non-boolean value for an enum-typed query context key, e.g. context {"vectorize": 1} or {"someEnumKey": {"a":1}} passed to QueryContexts.getEnum via DruidQuery.execute or a native query JSON body.

Common situations: Programmatic query builders using raw Object values for context; JSON APIs where numbers are submitted where strings are expected; templating tools that interpolate numbers (0/1) for enum flags.

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/9e45a44730eb6094. Report an issue: GitHub.