{"record":{"id":"1a24445891a2727d","repo":"redis/jedis","slug":"agg-min-policy-requires-comparable-types-or-keyval","errorCode":null,"errorMessage":"AGG_MIN policy requires Comparable types or KeyValue, but got: ${min.getClass().getName()} and ${input.getClass().getName()}","messagePattern":"AGG_MIN 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/MinAggregator.java","lineNumber":40,"sourceCode":"      return;\n    }\n\n    // Handle KeyValue types\n    if (min instanceof KeyValue && input instanceof KeyValue) {\n      min = (T) aggregateKeyValueMin((KeyValue<?, ?>) min, (KeyValue<?, ?>) input);\n      return;\n    }\n\n    // Handle Comparable types\n    if (min instanceof Comparable && input instanceof Comparable) {\n      Comparable<Object> minComp = (Comparable<Object>) min;\n      if (minComp.compareTo(input) > 0) {\n        min = input;\n      }\n      return;\n    }\n\n    throw new UnsupportedAggregationException(\n        \"AGG_MIN policy requires Comparable types or KeyValue, but got: \" + min.getClass().getName()\n            + \" and \" + input.getClass().getName());\n  }\n\n  @Override\n  public T getResult() {\n    return min;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private KeyValue<?, ?> aggregateKeyValueMin(KeyValue<?, ?> kv1, KeyValue<?, ?> kv2) {\n    Object minKey = ((Comparable<Object>) kv1.getKey()).compareTo(kv2.getKey()) <= 0 ? kv1.getKey()\n        : kv2.getKey();\n    Object minValue = ((Comparable<Object>) kv1.getValue()).compareTo(kv2.getValue()) <= 0\n        ? kv1.getValue()\n        : kv2.getValue();\n    return new KeyValue<>(minKey, minValue);\n  }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/executors/aggregators/MinAggregator.java#L22-L58","documentation":"MinAggregator.add throws UnsupportedAggregationException when the current min value is neither Comparable nor a KeyValue, so AGG_MIN cannot order the elements. Same contract as MaxAggregator but for the minimum.","triggerScenarios":"Calling add() with an operand that is not Comparable and not KeyValue, or whose compareTo is incompatible with the accumulated min.","commonSituations":"Aggregating raw byte arrays or custom objects returned by module commands; mixing types (String then Long) across add() calls.","solutions":["Ensure all values passed to add() are Comparable and mutually comparable, or KeyValue instances","Normalize types before aggregation (e.g. parse all to Long/Double)","Handle non-comparable data outside the aggregator"],"exampleFix":"// before\nminAgg.add(obj);\n// after\nif (obj instanceof Comparable) { minAgg.add(obj); } else { minAgg.add(Long.valueOf(obj.hashCode())); }","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof Comparable) && !(value instanceof KeyValue)) { throw new IllegalArgumentException(\"AGG_MIN needs Comparable or KeyValue\"); }","typeGuard":"boolean isMinCompatible(Object o) { return o instanceof Comparable || o instanceof KeyValue; }","tryCatchPattern":"try { minAgg.add(value); } catch (UnsupportedAggregationException e) { log.error(\"Non-comparable value: {}\", value.getClass()); throw e; }","preventionTips":["Only aggregate Comparable or KeyValue results","Normalize to one Comparable type before aggregation","Avoid mixing String and numeric types across add() calls"],"tags":["aggregation","comparable","type-mismatch","agg-min"],"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"}