{"record":{"id":"363777b6fb9d0ca1","repo":"grpc/grpc-java","slug":"value-s-for-idx-d-in-s-is-not-string","errorCode":null,"errorMessage":"value '%s' for idx %d in '%s' is not string","messagePattern":"value '(.+?)' for idx (.+?) in '(.+?)' is not string","errorType":"validation","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/JsonUtil.java","lineNumber":263,"sourceCode":"    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    }\n    return (List<Map<String, ?>>) rawList;\n  }\n\n  /**\n   * Casts a list of unchecked JSON values to a list of String. If the given list\n   * contains a value that is not a String, throws an exception.\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static List<String> checkStringList(List<?> rawList) {\n    for (int i = 0; i < rawList.size(); i++) {\n      if (!(rawList.get(i) instanceof String)) {\n        throw new ClassCastException(\n            String.format(\n                Locale.US,\n                \"value '%s' for idx %d in '%s' is not string\", rawList.get(i), i, rawList));\n      }\n    }\n    return (List<String>) rawList;\n  }\n\n  private static final long DURATION_SECONDS_MIN = -315576000000L;\n  private static final long DURATION_SECONDS_MAX = 315576000000L;\n\n  /**\n   * Parse from a string to produce a duration.  Copy of\n   * {@link com.google.protobuf.util.Durations#parse}.\n   *\n   * @return A Duration parsed from the string.\n   * @throws ParseException if parsing fails.\n   */","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/JsonUtil.java#L245-L281","documentation":"checkStringList validates that every element of a JSON list is a String and returns the list cast to List<String>. Non-string elements raise ClassCastException 'value ... is not string' with index and full list. Used via getListOfStrings for string-array config fields.","triggerScenarios":"JsonUtil.checkStringList(rawList) — reached via getListOfStrings — where an element is a number, boolean, object, or array, e.g. {\"languages\": [\"en\", 5]} or a null element.","commonSituations":"Service config lists (e.g. method names, user-agent lists) containing unquoted numbers or nulls; JSON generators emitting mixed-type arrays; hand-edited configs missing quotes.","solutions":["Quote every element of the list so all are strings.","Use the printed idx from the message to fix just the offending element.","Enforce array-of-string typing with JSON Schema or a builder API instead of raw JSON."],"exampleFix":"// before\n{\"supportedLocales\": [\"en\", 5, null]}\n// after\n{\"supportedLocales\": [\"en\", \"5\"]}","handlingStrategy":"validation","validationCode":"Object v = config.get(\"supportedLocales\");\nif (v instanceof List) {\n  for (Object e : (List<?>) v) {\n    if (!(e instanceof String)) {\n      throw new IllegalArgumentException(\"supportedLocales elements must be strings, got: \" + e);\n    }\n  }\n}","typeGuard":"boolean isListOfStrings(Object v) {\n  return v instanceof List && ((List<?>) v).stream().allMatch(e -> e instanceof String);\n}","tryCatchPattern":"try {\n  List<String> l = JsonUtil.checkStringList(rawList);\n} catch (ClassCastException e) {\n  log.error(\"List-of-strings config field malformed: \" + e.getMessage());\n}","preventionTips":["Quote every element in string arrays.","Reject null/mixed-type arrays at config load.","Prefer gRPC's typed ServiceConfig builders over raw JSON maps."],"tags":["grpc","json","config","type"],"backgroundTag":"schema-validation-failed","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"}