{"record":{"id":"9bee73af894a391e","repo":"grpc/grpc-java","slug":"value-s-for-key-s-in-s-is-not-object","errorCode":null,"errorMessage":"value '%s' for key '%s' in '%s' is not object","messagePattern":"value '(.+?)' for key '(.+?)' in '(.+?)' is not object","errorType":"validation","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/JsonUtil.java","lineNumber":92,"sourceCode":"      return null;\n    }\n    return checkStringList(list);\n  }\n\n  /**\n   * Gets an object from an object for the given key.  If the key is not present, this returns null.\n   * If the value is not a Map, throws an exception.\n   */\n  @SuppressWarnings(\"unchecked\")\n  @Nullable\n  public static Map<String, ?> getObject(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 Map)) {\n      throw new ClassCastException(\n          String.format(\"value '%s' for key '%s' in '%s' is not object\", value, key, obj));\n    }\n    return (Map<String, ?>) value;\n  }\n\n  /**\n   * Gets a number from an object for the given key.  If the key is not present, this returns null.\n   * If the value does not represent a double, throws an exception.\n   */\n  @Nullable\n  public static Double getNumberAsDouble(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 Double) {\n      return (Double) value;","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/JsonUtil.java#L74-L110","documentation":"JsonUtil.getObject retrieves a key from a parsed JSON object and requires the value to be a JSON object (Map). If the key exists with any other type, it throws ClassCastException('value ... is not object'), embedding the offending value, key, and parent object in the message.","triggerScenarios":"Calling getObject/getList-of-objects on a JSON config where the key holds a scalar or array instead of a nested object — e.g. xDS bootstrap 'node' or 'xds_server' written as a string, or a nested section accidentally flattened.","commonSituations":"Hand-written gRPC service config / xDS bootstrap files with wrong nesting; version drift where a field changed from object to scalar between config generators; copy-paste errors merging JSON sections.","solutions":["Fix the JSON so the key maps to an object: \"key\": {...} not \"key\": \"...\"","Validate bootstrap/service-config JSON against the gRPC schema before startup","Open the file named indirectly by the message and re-check the nesting of that key","Regenerate the config with the tooling's current version to eliminate stale shapes"],"exampleFix":"// before\n{\"xds_server\": \"trafficdirector.googleapis.com\"}\n// after\n{\"xds_server\": {\"server_uri\": \"trafficdirector.googleapis.com\", \"channel_creds\": [...]}}","handlingStrategy":"validation","validationCode":"Object v = cfg.get(\"node\");\nif (v != null && !(v instanceof Map)) throw new IllegalArgumentException(\"node must be a JSON object\");","typeGuard":"@SuppressWarnings(\"unchecked\")\nMap<String,?> asObject(Object v) { return v instanceof Map ? (Map<String,?>) v : null; }","tryCatchPattern":"try { JsonUtil.getObject(bootstrap, \"node\"); }\ncatch (ClassCastException e) { log.error(\"bad xDS bootstrap: {}\", e.getMessage()); throw new InvalidConfigException(e); }","preventionTips":["Schema-validate xDS bootstrap and service-config files before startup","Watch for field-shape changes when upgrading config generators","Keep nesting correct: objects for sections, arrays for lists"],"tags":["grpc","json","config","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}