{"record":{"id":"736143eaffa338f4","repo":"redis/jedis","slug":"operationname-requires-boolean-long-arraylist","errorCode":null,"errorMessage":"${operationName} requires Boolean, Long, ArrayList<Boolean>, or ArrayList<Long>, but got: ${input.getClass().getName()}","messagePattern":"(.+?) requires Boolean, Long, ArrayList<Boolean>, or ArrayList<Long>, but got: (.+?)","errorType":"exception","errorClass":"UnsupportedAggregationException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/executors/aggregators/LogicalBinaryAggregator.java","lineNumber":31,"sourceCode":"  private final String operationName;\n\n  protected LogicalBinaryAggregator(String operationName) {\n    this.operationName = operationName;\n  }\n\n  @Override\n  public void add(T input) {\n    if (input == null) {\n      return; // ignore nulls\n    }\n\n    if (result == null) {\n      // First non-null input initializes the result\n      if (input instanceof Boolean || input instanceof Long || input instanceof ArrayList) {\n        result = input;\n        return;\n      } else {\n        throw new UnsupportedAggregationException(operationName\n            + \" requires Boolean, Long, ArrayList<Boolean>, or ArrayList<Long>, but got: \"\n            + input.getClass().getName());\n      }\n    }\n\n    // Handle Boolean\n    if (result instanceof Boolean && input instanceof Boolean) {\n      result = (T) Boolean.valueOf(applyBooleanOp((Boolean) result, (Boolean) input));\n      return;\n    }\n\n    // Handle Long\n    if (result instanceof Long && input instanceof Long) {\n      boolean existingBool = (Long) result != 0;\n      boolean newBool = (Long) input != 0;\n      result = (T) Long.valueOf(applyBooleanOp(existingBool, newBool) ? 1L : 0L);\n      return;\n    }","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/executors/aggregators/LogicalBinaryAggregator.java#L13-L49","documentation":"LogicalBinaryAggregator merges Boolean/Long replies from a two-shard logical broadcast (e.g. EXISTS-style checks with ALL-SUCC / ANY-SUCC policies). The first non-null input must be Boolean, Long, or an ArrayList; anything else throws UnsupportedAggregationException with the actual type. It enforces that logical operations only aggregate boolean-like results.","triggerScenarios":"Executing a multi-shard logical command (operationName like ANY-SUCC/ALL-SUCC aggregation) whose Builder produces a reply type other than Boolean/Long/ArrayList — e.g. a String status reply or a byte[] being aggregated.","commonSituations":"Custom or module commands registered with a logical response policy but parsed to String/byte[]; wiring a broadcast EXISTS-like command with a generic OBJECT builder instead of BuilderFactory.BOOLEAN/LONG.","solutions":["Ensure the command's Builder converts replies to Boolean or Long (BuilderFactory.BOOLEAN / LONG) before aggregation.","Use a non-logical response policy if the command genuinely returns other types.","For multi-value results, parse into ArrayList<Boolean>/ArrayList<Long> so the aggregator accepts them."],"exampleFix":"// before\nnew CommandObject<>(args, BuilderFactory.STRING)   // String fed to logical aggregator\n// after\nnew CommandObject<>(args, BuilderFactory.BOOLEAN)  // Boolean accepted by logical aggregator","handlingStrategy":"type-guard","validationCode":"Object reply = jedis.sendCommand(cmd);\nif (!(reply instanceof Boolean || reply instanceof Long || reply instanceof ArrayList)) {\n  throw new IllegalStateException(\"logical broadcast requires Boolean/Long replies\");\n}","typeGuard":"boolean isLogicalReply(Object r) {\n  return r instanceof Boolean || r instanceof Long || r instanceof ArrayList;\n}","tryCatchPattern":"try {\n  return logicalBroadcast();\n} catch (UnsupportedAggregationException e) {\n  logger.error(\"bad reply type for logical op: {}\", e.getMessage());\n  throw new IllegalStateException(e);\n}","preventionTips":["Parse logical command replies with BuilderFactory.BOOLEAN or BuilderFactory.LONG","Reserve ALL-SU/ANY-SU style policies for boolean-returning commands","Add unit tests asserting the Builder output type before broadcasting"],"tags":["cluster","aggregation","response-policy","type-mismatch","logical"],"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"}