{"record":{"id":"932b3a2ed9f70121","repo":"redis/jedis","slug":"agg-max-policy-requires-comparable-types-or-keyval","errorCode":null,"errorMessage":"AGG_MAX policy requires Comparable types or KeyValue, but got: ${max.getClass().getName()} and ${input.getClass().getName()}","messagePattern":"AGG_MAX policy requires Comparable types or KeyValue, but got: (.+?) and (.+?)","errorType":"exception","errorClass":"UnsupportedAggregationException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/executors/aggregators/MaxAggregator.java","lineNumber":40,"sourceCode":"      return;\n    }\n\n    // Handle KeyValue types\n    if (max instanceof KeyValue && input instanceof KeyValue) {\n      max = (T) aggregateKeyValueMax((KeyValue<?, ?>) max, (KeyValue<?, ?>) input);\n      return;\n    }\n\n    // Handle Comparable types\n    if (max instanceof Comparable && input instanceof Comparable) {\n      Comparable<Object> maxComp = (Comparable<Object>) max;\n      if (maxComp.compareTo(input) < 0) {\n        max = input;\n      }\n      return;\n    }\n\n    throw new UnsupportedAggregationException(\n        \"AGG_MAX policy requires Comparable types or KeyValue, but got: \" + max.getClass().getName()\n            + \" and \" + input.getClass().getName());\n  }\n\n  @Override\n  public T getResult() {\n    return max;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private KeyValue<?, ?> aggregateKeyValueMax(KeyValue<?, ?> kv1, KeyValue<?, ?> kv2) {\n    Object maxKey = ((Comparable<Object>) kv1.getKey()).compareTo(kv2.getKey()) >= 0 ? kv1.getKey()\n        : kv2.getKey();\n    Object maxValue = ((Comparable<Object>) kv1.getValue()).compareTo(kv2.getValue()) >= 0\n        ? kv1.getValue()\n        : kv2.getValue();\n    return new KeyValue<>(maxKey, maxValue);\n  }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/executors/aggregators/MaxAggregator.java#L22-L58","documentation":"MaxAggregator.add throws UnsupportedAggregationException when the current max value is neither Comparable nor a KeyValue, so no comparison can be performed. AGG_MAX requires elements that can be ordered against each other.","triggerScenarios":"Calling add() with a non-Comparable, non-KeyValue object, e.g. a byte[] or a POJO without Comparable implementation, or a Comparable whose compareTo throws ClassCastException against the input.","commonSituations":"Aggregating heterogeneous command results; feeding serialized values (String vs binary) into AGG_MAX; custom result types not wrapped in KeyValue.","solutions":["Feed Comparable types (String, Long, Double, etc.) or redis.clients.jedis.args.KeyValue instances into the aggregator","Convert/parse the value into a Comparable form before calling add()","Use a custom aggregation outside this aggregator for non-comparable data"],"exampleFix":"// before\nmaxAgg.add(new byte[]{1});\n// after\nmaxAgg.add(Long.valueOf(bytes.length));","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof Comparable) && !(value instanceof KeyValue)) { throw new IllegalArgumentException(\"AGG_MAX needs Comparable or KeyValue\"); }","typeGuard":"boolean isMaxCompatible(Object o) { return o instanceof Comparable || o instanceof KeyValue; }","tryCatchPattern":"try { maxAgg.add(value); } catch (UnsupportedAggregationException e) { log.error(\"Non-comparable value: {}\", value.getClass()); throw e; }","preventionTips":["Only aggregate Comparable or KeyValue results","Parse raw/binary values into Comparable types first","Keep operand types consistent across add() calls"],"tags":["aggregation","comparable","type-mismatch","agg-max"],"backgroundTag":"type-mismatch","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"}