{"record":{"id":"21bbd356b54051d7","repo":"grpc/grpc-java","slug":"the-value-of-the-map-entry-entry-is-of-type","errorCode":null,"errorMessage":"The value of the map entry '${entry}' is of type '${value.getClass()}', which is not supported","messagePattern":"The value of the map entry '(.+?)' is of type '(.+?)', which is not supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/ManagedChannelImplBuilder.java","lineNumber":632,"sourceCode":"          entry.getKey() instanceof String,\n          \"The key of the entry '%s' is not of String type\", entry);\n\n      String key = (String) entry.getKey();\n      Object value = entry.getValue();\n      if (value == null) {\n        parsedMap.put(key, null);\n      } else if (value instanceof Map) {\n        parsedMap.put(key, checkMapEntryTypes((Map<?, ?>) value));\n      } else if (value instanceof List) {\n        parsedMap.put(key, checkListEntryTypes((List<?>) value));\n      } else if (value instanceof String) {\n        parsedMap.put(key, value);\n      } else if (value instanceof Number) {\n        parsedMap.put(key, ((Number) value).doubleValue());\n      } else if (value instanceof Boolean) {\n        parsedMap.put(key, value);\n      } else {\n        throw new IllegalArgumentException(\n            \"The value of the map entry '\" + entry + \"' is of type '\" + value.getClass()\n                + \"', which is not supported\");\n      }\n    }\n    return Collections.unmodifiableMap(parsedMap);\n  }\n\n  private static List<?> checkListEntryTypes(List<?> list) {\n    List<Object> parsedList = new ArrayList<>(list.size());\n    for (Object value : list) {\n      if (value == null) {\n        parsedList.add(null);\n      } else if (value instanceof Map) {\n        parsedList.add(checkMapEntryTypes((Map<?, ?>) value));\n      } else if (value instanceof List) {\n        parsedList.add(checkListEntryTypes((List<?>) value));\n      } else if (value instanceof String) {\n        parsedList.add(value);","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/ManagedChannelImplBuilder.java#L614-L650","documentation":"When building the channel from option maps (e.g. raw service-config or custom option maps), ManagedChannelImplBuilder normalizes each map entry value to String, Double, or Boolean. A value of any other type (e.g. nested Map, List, null wrapper) cannot be represented and triggers this IllegalArgumentException naming the offending key and its class.","triggerScenarios":"Passing a Map<String,?> channel option or config map containing a nested Map, List, or custom object value for a key, then invoking the internal builder's map-parsing path.","commonSituations":"Constructing service config options programmatically with nested structures; JSON configs deserialized into java.util.LinkedHashMap values leaking into option maps; client interceptor option maps carrying POJOs.","solutions":["Flatten nested values to supported types: String, Number, or Boolean before setting the option.","Serialize nested structures to a JSON string if the option accepts textual config.","Log/inspect the offending key ('entry') and fix its value type.","Use typed builder methods (e.g. .maxInboundMessageSize(int)) instead of raw maps."],"exampleFix":"// before\nMap<String, Object> opts = new HashMap<>();\nopts.put(\"serviceConfig\", someNestedMap); // Map value\neasyBuilder.build();\n// after\nopts.put(\"serviceConfig\", jsonAsString); // String value","handlingStrategy":"validation","validationCode":"static void checkOptionTypes(Map<String, Object> opts) {\n  for (Map.Entry<String, Object> e : opts.entrySet()) {\n    Object v = e.getValue();\n    if (!(v instanceof String || v instanceof Number || v instanceof Boolean)) {\n      throw new IllegalArgumentException(\"option '\" + e.getKey() + \"' has unsupported type \" + v.getClass());\n    }\n  }\n}","typeGuard":"boolean isSupportedOptionValue(Object v) {\n  return v instanceof String || v instanceof Number || v instanceof Boolean;\n}","tryCatchPattern":"try {\n  buildChannel(options);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"which is not supported\")) {\n    log.error(\"Bad option map: {}\", e.getMessage());\n  } else throw e;\n}","preventionTips":["Restrict option maps to String/Number/Boolean values.","Convert JSON parse trees to scalars before use.","Use typed builder setters instead of raw maps."],"tags":["grpc","config","type-mismatch","validation"],"backgroundTag":"config-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"}