apache/druid · error · BadQueryContextException

Expected key [%s] to be a Float, but got [%s]

Error message

Expected key [%s] to be a Float, but got [%s]

What it means

QueryContexts.getAsFloat(key, value) throws badTypeException with this message when the context value is neither null, a Number, nor a String — its class (Boolean, Map, List, ...) cannot be converted to a float. The exception reports the key and the value's actual runtime type.

Source

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

  /**
   * Get the value of a context value as an {@code Float}. The value is expected
   * to be {@code null}, a string or a {@code Number} object.
   */
  public static Float getAsFloat(final String key, final Object value)
  {
    if (value == null) {
      return null;
    } else if (value instanceof Number) {
      return ((Number) value).floatValue();
    } else if (value instanceof String) {
      try {
        return Float.parseFloat((String) value);
      }
      catch (NumberFormatException ignored) {
        throw badValueException(key, "in float format", value);
      }
    }
    throw badTypeException(key, "a Float", value);
  }

  public static float getAsFloat(
      final String key,
      final Object value,
      final float defaultValue
  )
  {
    Float val = getAsFloat(key, value);
    return val == null ? defaultValue : val;
  }

  public static HumanReadableBytes getAsHumanReadableBytes(
      final String key,
      final Object value,
      final HumanReadableBytes defaultValue
  )
  {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Fix the query context JSON so the key holds a JSON number or numeric string.
  2. In code, put a Float/Double: context.put(key, 0.5d).
  3. Verify the key name to make sure the value wasn't meant for a different (object-typed) key.
  4. Catch the exception and fall back to the default value.

Example fix

// before
{"threshold": [0.5]}  // array -> IAE
// after
{"threshold": 0.5}
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = context.get(key);
if (v != null && !(v instanceof Number) && !(v instanceof String)) {
  throw new IllegalArgumentException("Context key '" + key + "' must be numeric, got: " + v.getClass().getSimpleName());
}

Type guard

boolean isContextNumber(Object v) { return v == null || v instanceof Number || v instanceof String; }

Try / catch

try {
  return query.getContextValue(key, defaultFloat);
} catch (IllegalArgumentException e) {
  LOG.warn(e, "Wrong type for context key [%s], using default", key);
  return defaultFloat;
}

Prevention

When it happens

Trigger: Calling QueryContexts.getAsFloat(key, value) or query.getContextValue(key, float default) when the context map stores a Boolean, JSON object/array, or other object under a float-typed context key.

Common situations: A boolean switch placed under a numeric threshold key; nested configuration objects accidentally assigned to a scalar context key; query builders passing raw JSON nodes into the context.

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/563cb2a6a43ea0a0. Report an issue: GitHub.