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,
actualView on GitHub (pinned to 9b90983fd2)
Solutions
- Quote the context value as a string matching an enum constant name, e.g. "vectorize": "true" instead of 1.
- Use QueryContexts's typed setters or ensure your query builder serializes the field as a JSON string.
- 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
- Serialize enum context values as JSON strings in query builders.
- Avoid interpolating numbers for boolean/enum flags in templates.
- Add unit tests asserting the JSON shape of emitted query context.
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
- Timeout [timeout] must be a non negative value, but was %d
- Per-segment timeout [timeoutPerSegmentQuery] must be a non n
- needs a number as its first argument but got %s instead
- needs a LONG as its second argument but got %s instead
- Expected key [%s] to be a String, but got [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9e45a44730eb6094.
Report an issue: GitHub.