{"record":{"id":"cc4697945882e272","repo":"grpc/grpc-java","slug":"can-not-convert-status-code-status-to-status-co","errorCode":null,"errorMessage":"Can not convert status code ${status} to Status.Code, because its type is ${type}","messagePattern":"Can not convert status code (.+?) to Status\\.Code, because its type is (.+?)","errorType":"validation","errorClass":"VerifyException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/ServiceConfigUtil.java","lineNumber":173,"sourceCode":"\n  private static Set<Status.Code> getStatusCodesFromList(List<?> statuses) {\n    EnumSet<Status.Code> codes = EnumSet.noneOf(Status.Code.class);\n    for (Object status : statuses) {\n      Status.Code code;\n      if (status instanceof Double) {\n        Double statusD = (Double) status;\n        int codeValue = statusD.intValue();\n        verify((double) codeValue == statusD, \"Status code %s is not integral\", status);\n        code = Status.fromCodeValue(codeValue).getCode();\n        verify(code.value() == statusD.intValue(), \"Status code %s is not valid\", status);\n      } else if (status instanceof String) {\n        try {\n          code = Status.Code.valueOf((String) status);\n        } catch (IllegalArgumentException iae) {\n          throw new VerifyException(\"Status code \" + status + \" is not valid\", iae);\n        }\n      } else {\n        throw new VerifyException(\n            \"Can not convert status code \" + status + \" to Status.Code, because its type is \"\n                + status.getClass());\n      }\n      codes.add(code);\n    }\n    return Collections.unmodifiableSet(codes);\n  }\n\n  static Set<Status.Code> getRetryableStatusCodesFromRetryPolicy(Map<String, ?> retryPolicy) {\n    String retryableStatusCodesKey = \"retryableStatusCodes\";\n    Set<Status.Code> codes = getListOfStatusCodesAsSet(retryPolicy, retryableStatusCodesKey);\n    verify(codes != null, \"%s is required in retry policy\", retryableStatusCodesKey);\n    verify(!codes.contains(Status.Code.OK), \"%s must not contain OK\", retryableStatusCodesKey);\n    return codes;\n  }\n\n  @Nullable\n  static Integer getMaxAttemptsFromHedgingPolicy(Map<String, ?> hedgingPolicy) {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/ServiceConfigUtil.java#L155-L191","documentation":"In ServiceConfigUtil.getStatusCodesFromList, each status entry must be a String naming a Status.Code or an Integer code value. If the JSON entry is neither (e.g. a boolean, nested object, or null), this VerifyException reports the unexpected type. The library throws it to reject malformed service configs early rather than fail obscurely later.","triggerScenarios":"A retryableStatusCodes entry in the service config is a non-string, non-integer JSON value such as true, null, {\"code\":14}, or [14]; reached via getListOfStatusCodesAsSet during service config parsing.","commonSituations":"Malformed service config where status codes were nested in objects or left as booleans/null; templating tools that substituted placeholder values incorrectly; YAML/JSON conversion mistakes.","solutions":["Inspect the retryableStatusCodes array in the service config and ensure every element is a string (status name) or integer (code value)","Remove null/boolean/object entries or convert them to proper code names like \"DEADLINE_EXCEEDED\"","Validate the service config JSON against the gRPC service config schema before deployment"],"exampleFix":"// before\n\"retryableStatusCodes\": [\"UNAVAILABLE\", {\"code\": 14}]\n// after\n\"retryableStatusCodes\": [\"UNAVAILABLE\", \"RESOURCE_EXHAUSTED\"]","handlingStrategy":"type-guard","validationCode":"// Before parsing, check element types\nfor (Object o : rawList) {\n  if (!(o instanceof String) && !(o instanceof Integer)) {\n    throw new IllegalArgumentException(\"retryableStatusCodes entries must be string or int, got: \"\n        + (o == null ? \"null\" : o.getClass().getSimpleName()));\n  }\n}","typeGuard":"boolean isValidStatusCodeEntry(Object o) {\n  return o instanceof String || o instanceof Integer;\n}","tryCatchPattern":"try {\n  codes = ServiceConfigUtil.getListOfStatusCodesAsSet(rawList);\n} catch (VerifyException e) {\n  log.error(\"retryableStatusCodes contains non string/int entry\");\n  throw new ConfigInvalidException(e);\n}","preventionTips":["Validate JSON shape (array of string|int) before handing config to gRPC","Watch for template/placeholder substitution producing nulls or booleans","Add JSON-schema validation of the service config as a deploy gate"],"tags":["grpc","service-config","type-mismatch","status-codes"],"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"}