{"record":{"id":"267f45fea5c5d729","repo":"redis/jedis","slug":"keysvalues-must-contain-an-even-number-of-elements","errorCode":null,"errorMessage":"keysValues must contain an even number of elements (key-value pairs)","messagePattern":"keysValues must contain an even number of elements \\(key-value pairs\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/ClusterCommandObjects.java","lineNumber":298,"sourceCode":"   * @param insertKeyCount if true, inserts the number of keys after the command but before the keys (for commands like MSETEX)\n   * @return a list of CommandArguments objects, each containing only keys/values that belong to the same hash slot,\n   *         preserving the original key order\n   * @throws IllegalArgumentException if valueAdder is provided and keysOrKeysValues has odd length\n   */\n  private <T> List<CommandArguments> groupArgumentsByKeyValueHashSlotImpl(\n      CommandArguments args,\n      T[] keysOrKeysValues,\n      IParams params,\n      Function<T, Integer> slotCalculator,\n      BiConsumer<CommandArguments, T> keyAdder,\n      BiConsumer<CommandArguments, T> valueAdder,\n      boolean insertKeyCount) {\n\n    boolean keyValueMode = valueAdder != null;\n    int step = keyValueMode ? 2 : 1;\n\n    if (keyValueMode && keysOrKeysValues.length % 2 != 0) {\n      throw new IllegalArgumentException(\"keysValues must contain an even number of elements (key-value pairs)\");\n    }\n\n    if (keysOrKeysValues.length == 0) {\n      return new ArrayList<>();\n    }\n\n    // Wrap slotCalculator to apply keyPreProcessor transformation before slot calculation.\n    // This ensures keys are grouped by their actual slot (after preprocessing), not the original key's slot.\n    Function<T, Integer> effectiveSlotCalculator = keyPreProcessor != null\n        ? key -> calculateSlotFromPreprocessedKey(keyPreProcessor.actualKey(key))\n        : slotCalculator;\n\n    // Group consecutive keys with the same slot together, preserving input order\n    // Non-consecutive keys with the same slot will be in separate commands\n    List<CommandArguments> result = new ArrayList<>();\n\n    int currentSlot = -1;\n    List<T> currentGroup = new ArrayList<>();","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/ClusterCommandObjects.java#L280-L316","documentation":"A generic guard inside the private cluster-slot grouping helper: when the valueAdder (key-value pair mode) is used, keysOrKeysValues must alternate key,value entries; an odd-length array means a key or value is missing, so pairs cannot be split and routed to hash slots. Fires before any command is sent.","triggerScenarios":"Thrown at src/main/java/redis/clients/jedis/ClusterCommandObjects.java:298 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the caller so the array passed to the command contains complete key,value pairs (even number of elements)","Check array length before invoking the command and reject odd-length input early","Use the keys-only variant (groupArgumentsByKeyHashSlot) if you intend to pass keys without values"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}