{"record":{"id":"38ceb4dbf99e57fe","repo":"apache/druid","slug":"expected-key-s-to-be-a-boolean-but-got-s","errorCode":null,"errorMessage":"Expected key [%s] to be a Boolean, but got [%s]","messagePattern":"Expected key \\[(.+?)\\] to be a Boolean, but got \\[(.+?)\\]","errorType":"validation","errorClass":"BadQueryContextException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/QueryContexts.java","lineNumber":341,"sourceCode":"      return (String) value;\n    }\n    throw badTypeException(key, \"a String\", value);\n  }\n\n  @Nullable\n  public static Boolean getAsBoolean(\n      final String key,\n      final Object value\n  )\n  {\n    if (value == null) {\n      return null;\n    } else if (value instanceof String) {\n      return Boolean.parseBoolean((String) value);\n    } else if (value instanceof Boolean) {\n      return (Boolean) value;\n    }\n    throw badTypeException(key, \"a Boolean\", value);\n  }\n\n  /**\n   * Get the value of a context value as a {@code boolean}. The value is expected\n   * to be {@code null}, a string or a {@code Boolean} object.\n   */\n  public static boolean getAsBoolean(\n      final String key,\n      final Object value,\n      final boolean defaultValue\n  )\n  {\n    Boolean val = getAsBoolean(key, value);\n    return val == null ? defaultValue : val;\n  }\n\n  @Nullable\n  public static Integer getAsInt(String key, Object value)","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/QueryContexts.java#L323-L359","documentation":"QueryContexts.getAsBoolean(key, value) throws this when a query context value must be read as a Boolean but is neither null, a String, nor a Boolean instance. Context values arrive as arbitrary JSON, so the getter coerces strings via Boolean.parseBoolean and rejects every other type. The exception reports the key and the offending value's actual type.","triggerScenarios":"Calling QueryContexts.getAsBoolean(key, value) or query.getContextValue(key, boolean default) when the context map stores a Number, Map, List, or other non-boolean/non-string object for a boolean context key (e.g. useCache, populateCache, vectorize-enabled style flags).","commonSituations":"A client sends a boolean flag as a JSON number (0/1) instead of true/false; a proxy or query builder inserts an Integer for a flag; a config migration changed the value type stored under a context key.","solutions":["Send the context flag as a JSON boolean (true/false) or the string \"true\"/\"false\".","If you control the code path, wrap the read: value instanceof Boolean || value instanceof String, else fix the value before the call.","Convert numeric flags at the producer: context.put(key, Boolean.parseBoolean(String.valueOf(raw))).","Catch the exception and fall back to the documented default for that context key."],"exampleFix":"// before\n{\"useCache\": 1}   // JSON number -> IAE\n// after\n{\"useCache\": true}  // or \"useCache\": \"true\"","handlingStrategy":"validation","validationCode":"Object v = context.get(key);\nif (v != null && !(v instanceof Boolean) && !(v instanceof String)) {\n  throw new IllegalArgumentException(\"Context key '\" + key + \"' must be boolean or string, got: \" + v.getClass().getSimpleName());\n}","typeGuard":"boolean isContextBoolean(Object v) { return v == null || v instanceof Boolean || v instanceof String; }","tryCatchPattern":"try {\n  return query.getContextValue(key, defaultValue);\n} catch (IllegalArgumentException e) {\n  LOG.warn(e, \"Invalid boolean for context key [%s], using default\", key);\n  return defaultValue;\n}","preventionTips":["Send boolean context flags as JSON true/false, never 0/1 numbers.","Note Boolean.parseBoolean treats any string other than \"true\" (ignoring case) as false — prefer real booleans.","Keep flag values consistent when migrating configs between API versions."],"tags":["druid","query-context","type-mismatch","boolean"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}