redis/jedis · error · UnsupportedAggregationException

AGG_SUM policy requires numeric type, but got

Error message

AGG_SUM policy requires numeric type, but got: ${newReply.getClass().getName()}

What it means

ClusterReplyAggregator combines replies broadcast to multiple shards. For the AGG_SUM response policy it requires every reply to be numeric (Long/Double); when the first non-null reply is any other type it throws UnsupportedAggregationException naming the offending type. The delegate aggregator is lazily initialized from the first reply, so a non-numeric first reply fails immediately.

Solutions

  1. Only apply the AGG_SUM policy to commands guaranteed to return numeric replies on all shards.
  2. Pre-validate the values stored in the targeted keys are integers/floats before broadcasting increment commands.
  3. Switch the response policy to one matching the actual reply type (e.g. DEFAULT or FIRST) in the command definition.
  4. Handle shard errors before aggregation so error replies aren't fed into the AGG_SUM aggregator.

Example fix

// before
CommandObject<Long> obj = new CommandObject<>(args(FLUSHDB).responsePolicy(ResponsePolicy.AGG_SUM), BuilderFactory.LONG);
// after
CommandObject<Long> obj = new CommandObject<>(args(INCRBY).key(key)
    .responsePolicy(ResponsePolicy.AGG_SUM), BuilderFactory.LONG);
Defensive patterns

Strategy: validation

Validate before calling

// ensure target keys hold numeric values before an AGG_SUM broadcast
Object v = jedis.get(key);
if (v != null && !v.toString().matches("-?\\d+(\\.\\d+)?")) {
  throw new IllegalStateException("key " + key + " is not numeric; AGG_SUM would fail");
}

Type guard

boolean isNumericReply(Object reply) { return reply instanceof Number; }

Try / catch

try {
  return broadcastSum();
} catch (UnsupportedAggregationException e) {
  logger.error("non-numeric reply under AGG_SUM: {}", e.getMessage());
  throw new IllegalStateException(e);
}

Prevention

When it happens

Trigger: Broadcasting commands with an AGG_SUM response policy where shards return non-numeric values — e.g. INCRBY on keys that hold non-integer strings returning an error reply/object, or a command whose builder attached AGG_SUM but returns strings/nulls.

Common situations: Aggregating INCR/INCRBY across cluster shards where some keys hold non-numeric values; misuse of the response-policy API wrapping commands that return strings (GET) with AGG_SUM; a shard returning an error object instead of a number.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/b658e31b9a07a41f. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/executors/aggregators/ClusterReplyAggregator.java:37

    this.policy = Objects.requireNonNull(policy, "policy cannot be null");
  }

  /**
   * Adds a new value to the aggregator. Null values are ignored.
   */
  @Override
  @SuppressWarnings("unchecked")
  public void add(T newReply) {
    if (newReply == null) {
      return; // ignore nulls
    }

    // Lazy initialization of delegate based on policy and first non-null value
    if (delegate == null) {
      switch (policy) {
        case AGG_SUM:
          if (!(newReply instanceof Number)) {
            throw new UnsupportedAggregationException(
                "AGG_SUM policy requires numeric type, but got: " + newReply.getClass().getName());
          }
          delegate = (Aggregator<T, T>) new SumAggregator<>(); // safe cast
          break;
        case AGG_MIN:
          delegate = new MinAggregator<>();
          break;
        case AGG_MAX:
          delegate = new MaxAggregator<>();
          break;
        case AGG_LOGICAL_AND:
          delegate = new LogicalAndAggregator<>();
          break;
        case AGG_LOGICAL_OR:
          delegate = new LogicalOrAggregator<>();
          break;
        case DEFAULT:
          delegate = new DefaultPolicyAggregator<>();

View on GitHub (pinned to 6dac31d4c2)