{"record":{"id":"4a23c96ab14f70b4","repo":"redis/jedis","slug":"unsupported-key-type-preprocessedkey-getclass","errorCode":null,"errorMessage":"Unsupported key type: ${preprocessedKey.getClass().getName()}","messagePattern":"Unsupported key type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/ClusterCommandObjects.java","lineNumber":357,"sourceCode":"\n    return result;\n  }\n\n  /**\n   * Calculates the hash slot for a preprocessed key.\n   *\n   * @param preprocessedKey the key after preprocessing (may be String, byte[], or Rawable)\n   * @return the hash slot for the key\n   */\n  private int calculateSlotFromPreprocessedKey(Object preprocessedKey) {\n    if (preprocessedKey instanceof byte[]) {\n      return JedisClusterCRC16.getSlot((byte[]) preprocessedKey);\n    } else if (preprocessedKey instanceof String) {\n      return JedisClusterCRC16.getSlot((String) preprocessedKey);\n    } else if (preprocessedKey instanceof redis.clients.jedis.args.Rawable) {\n      return JedisClusterCRC16.getSlot(((redis.clients.jedis.args.Rawable) preprocessedKey).getRaw());\n    }\n    throw new IllegalArgumentException(\"Unsupported key type: \" + preprocessedKey.getClass().getName());\n  }\n\n  /**\n   * Helper method to create a CommandArguments for a group of keys/values.\n   */\n  private <T> CommandArguments createCommandArgsForGroup(\n      CommandArguments args,\n      List<T> groupedElements,\n      IParams params,\n      BiConsumer<CommandArguments, T> keyAdder,\n      BiConsumer<CommandArguments, T> valueAdder,\n      boolean insertKeyCount,\n      int step) {\n\n    boolean keyValueMode = valueAdder != null;\n    CommandArguments slotArgs = commandArguments(args.getCommand());\n\n    // Insert key count after command but before keys (e.g., numkeys for MSETEX)","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/ClusterCommandObjects.java#L339-L375","documentation":"ClusterCommandObjects.calculateSlotFromPreprocessedKey computes the Redis Cluster hash slot for a key, but only understands byte[], String, and Rawable key representations. When a command is built with a key object of any other type, it cannot be routed to a cluster node, so an IllegalArgumentException is thrown naming the offending class.","triggerScenarios":"Calling any cluster command via UnifiedJedis/ClusterCommandObjects with a key argument that is neither byte[], String, nor a Rawable — e.g. a custom key wrapper object, an Integer/Long passed where a key is expected, or a CommandObject built with an unsupported preprocessed key type.","commonSituations":"Migrating code from a standalone Jedis setup to RedisClusterClient where keys were passed as arbitrary objects; wrapping keys in custom domain types and forgetting to call toString() or serialize; library users passing protocol objects that are neither byte[] nor Rawable.","solutions":["Convert the key to a supported type before passing it: call key.toString(), SafeEncoder.encode(key), or implement redis.clients.jedis.args.Rawable returning the encoded bytes.","If the key is a custom wrapper, extract the underlying String or byte[] representation at the call site.","Check for a version/API change: ensure you are passing the raw key value, not a CommandObject or other internal type, to the command method."],"exampleFix":"// before\ncluster.set(myKeyWrapper, value); // myKeyWrapper is a custom type\n// after\ncluster.set(myKeyWrapper.toString(), value);","handlingStrategy":"type-guard","validationCode":"private static Object toClusterKey(Object key) {\n  if (key instanceof String || key instanceof byte[] || key instanceof redis.clients.jedis.args.Rawable) return key;\n  return key.toString();\n}","typeGuard":"static boolean isClusterKey(Object k) {\n  return k instanceof String || k instanceof byte[] || k instanceof redis.clients.jedis.args.Rawable;\n}","tryCatchPattern":"try {\n  cluster.set(key, value);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unsupported key type\")) {\n    cluster.set(key.toString(), value);\n  } else throw e;\n}","preventionTips":["Always pass keys as String or byte[] in cluster mode.","Encode custom key objects with SafeEncoder.encode() before use.","Centralize key construction in one helper that normalizes types."],"tags":["redis-cluster","key-encoding","invalid-argument"],"backgroundTag":"unsupported-key-type","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}