{"record":{"id":"ca3e8fa2eace5616","repo":"grpc/grpc-java","slug":"value-s-for-key-s-in-s-is-not-boolean","errorCode":null,"errorMessage":"value '%s' for key '%s' in '%s' is not Boolean","messagePattern":"value '(.+?)' for key '(.+?)' in '(.+?)' is not Boolean","errorType":"validation","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/JsonUtil.java","lineNumber":233,"sourceCode":"      return parseDuration(value);\n    } catch (ParseException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  /**\n   * Gets a boolean from an object for the given key.  If the key is not present, this returns null.\n   * If the value is not a Boolean, throws an exception.\n   */\n  @Nullable\n  public static Boolean getBoolean(Map<String, ?> obj, String key) {\n    assert key != null;\n    if (!obj.containsKey(key)) {\n      return null;\n    }\n    Object value = obj.get(key);\n    if (!(value instanceof Boolean)) {\n      throw new ClassCastException(\n          String.format(\"value '%s' for key '%s' in '%s' is not Boolean\", value, key, obj));\n    }\n    return (Boolean) value;\n  }\n\n  /**\n   * Casts a list of unchecked JSON values to a list of checked objects in Java type.\n   * If the given list contains a value that is not a Map, throws an exception.\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static List<Map<String, ?>> checkObjectList(List<?> rawList) {\n    for (int i = 0; i < rawList.size(); i++) {\n      if (!(rawList.get(i) instanceof Map)) {\n        throw new ClassCastException(\n            String.format(\n                Locale.US, \"value %s for idx %d in %s is not object\", rawList.get(i), i, rawList));\n      }\n    }","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/JsonUtil.java#L215-L251","documentation":"getBoolean requires the value at the key to be a JSON Boolean; anything else raises ClassCastException 'is not Boolean'. It is used for boolean service-config flags (e.g. retry/health-check toggles), where strict typing prevents truthy-string bugs.","triggerScenarios":"JsonUtil.getBoolean(map, key) where value is a string \"true\"/\"false\", a 0/1 number, or any non-boolean type.","commonSituations":"Config written as {\"enableRetry\": \"true\"} (quoted) or {\"enableRetry\": 1}; converting YAML/env-based configs to JSON without type coercion.","solutions":["Use JSON true/false literals instead of \"true\"/\"false\" strings or 1/0.","Coerce the value in your config loader (map \"true\"/\"false\"/1/0 to booleans) before passing to gRPC.","Validate boolean fields with a schema before parsing."],"exampleFix":"// before\n{\"enableRetry\": \"true\"}\n// after\n{\"enableRetry\": true}","handlingStrategy":"type-guard","validationCode":"Object v = config.get(\"enableRetry\");\nif (v != null && !(v instanceof Boolean)) {\n  throw new IllegalArgumentException(\"enableRetry must be a JSON boolean, got: \" + v);\n}","typeGuard":"boolean isBoolean(Object v) { return v instanceof Boolean; }","tryCatchPattern":"try {\n  Boolean b = JsonUtil.getBoolean(config, \"enableRetry\");\n} catch (ClassCastException e) {\n  log.error(\"Boolean config field has wrong type: \" + e.getMessage());\n}","preventionTips":["Use JSON true/false literals, never \"true\"/\"false\" strings or 1/0.","Coerce env-var/booleans explicitly in your loader.","Schema-validate boolean fields."],"tags":["grpc","json","config","type"],"backgroundTag":"type-mismatch","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}