{"record":{"id":"b658e31b9a07a41f","repo":"redis/jedis","slug":"agg-sum-policy-requires-numeric-type-but-got-n","errorCode":null,"errorMessage":"AGG_SUM policy requires numeric type, but got: ${newReply.getClass().getName()}","messagePattern":"AGG_SUM policy requires numeric type, but got: (.+?)","errorType":"exception","errorClass":"UnsupportedAggregationException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/executors/aggregators/ClusterReplyAggregator.java","lineNumber":37,"sourceCode":"    this.policy = Objects.requireNonNull(policy, \"policy cannot be null\");\n  }\n\n  /**\n   * Adds a new value to the aggregator. Null values are ignored.\n   */\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public void add(T newReply) {\n    if (newReply == null) {\n      return; // ignore nulls\n    }\n\n    // Lazy initialization of delegate based on policy and first non-null value\n    if (delegate == null) {\n      switch (policy) {\n        case AGG_SUM:\n          if (!(newReply instanceof Number)) {\n            throw new UnsupportedAggregationException(\n                \"AGG_SUM policy requires numeric type, but got: \" + newReply.getClass().getName());\n          }\n          delegate = (Aggregator<T, T>) new SumAggregator<>(); // safe cast\n          break;\n        case AGG_MIN:\n          delegate = new MinAggregator<>();\n          break;\n        case AGG_MAX:\n          delegate = new MaxAggregator<>();\n          break;\n        case AGG_LOGICAL_AND:\n          delegate = new LogicalAndAggregator<>();\n          break;\n        case AGG_LOGICAL_OR:\n          delegate = new LogicalOrAggregator<>();\n          break;\n        case DEFAULT:\n          delegate = new DefaultPolicyAggregator<>();","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/executors/aggregators/ClusterReplyAggregator.java#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Only apply the AGG_SUM policy to commands guaranteed to return numeric replies on all shards.","Pre-validate the values stored in the targeted keys are integers/floats before broadcasting increment commands.","Switch the response policy to one matching the actual reply type (e.g. DEFAULT or FIRST) in the command definition.","Handle shard errors before aggregation so error replies aren't fed into the AGG_SUM aggregator."],"exampleFix":"// before\nCommandObject<Long> obj = new CommandObject<>(args(FLUSHDB).responsePolicy(ResponsePolicy.AGG_SUM), BuilderFactory.LONG);\n// after\nCommandObject<Long> obj = new CommandObject<>(args(INCRBY).key(key)\n    .responsePolicy(ResponsePolicy.AGG_SUM), BuilderFactory.LONG);","handlingStrategy":"validation","validationCode":"// ensure target keys hold numeric values before an AGG_SUM broadcast\nObject v = jedis.get(key);\nif (v != null && !v.toString().matches(\"-?\\\\d+(\\\\.\\\\d+)?\")) {\n  throw new IllegalStateException(\"key \" + key + \" is not numeric; AGG_SUM would fail\");\n}","typeGuard":"boolean isNumericReply(Object reply) { return reply instanceof Number; }","tryCatchPattern":"try {\n  return broadcastSum();\n} catch (UnsupportedAggregationException e) {\n  logger.error(\"non-numeric reply under AGG_SUM: {}\", e.getMessage());\n  throw new IllegalStateException(e);\n}","preventionTips":["Attach AGG_SUM only to commands returning numbers on every shard","Store only numeric data in keys aggregated with AGG_SUM","Convert shard error replies before aggregation","Document response policies with each custom command"],"tags":["cluster","aggregation","response-policy","type-mismatch","broadcast"],"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"}