{"record":{"id":"f8af903589d148dc","repo":"redis/jedis","slug":"count-or-exactly-must-be-specified","errorCode":null,"errorMessage":"COUNT or EXACTLY must be specified.","messagePattern":"COUNT or EXACTLY must be specified\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/params/LMoveMParams.java","lineNumber":62,"sourceCode":"  /**\n   * Move exactly {@code count} elements, or nothing (a {@code null} reply) if the source list does\n   * not hold that many, ordered by {@code order}. Mutually exclusive with\n   * {@link #count(int, ListMoveOrder)} (last call wins).\n   */\n  public LMoveMParams exactly(int count, ListMoveOrder order) {\n    if (order == null) {\n      throw new IllegalArgumentException(\"Ordering (OBO or BULK) must not be null.\");\n    }\n    this.selector = Keyword.EXACTLY;\n    this.count = count;\n    this.order = order;\n    return this;\n  }\n\n  @Override\n  public void addParams(CommandArguments args) {\n    if (selector == null || count == null) {\n      throw new IllegalArgumentException(\"COUNT or EXACTLY must be specified.\");\n    }\n    args.add(selector).add(count).add(order);\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) return true;\n    if (o == null || getClass() != o.getClass()) return false;\n    LMoveMParams that = (LMoveMParams) o;\n    return selector == that.selector && Objects.equals(count, that.count) && order == that.order;\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hash(selector, count, order);\n  }\n}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/params/LMoveMParams.java#L44-L80","documentation":"LMPOP-style multi-list move params must carry a COUNT or EXACTLY selector before being serialized. LMoveMParams.addParams() throws this IllegalArgumentException when neither count(...) nor exactly(...) was called, because the command arguments would be incomplete/invalid.","triggerScenarios":"Executing the multi-list LMOVE/LMPOP command with LMoveMParams built only via builder methods other than count()/exactly() — e.g. an empty new LMoveMParams() or one constructed by a factory that only set the order.","commonSituations":"Building params conditionally where both count and exactly branches were skipped; reusing a params object whose selector was expected to be set elsewhere; misunderstanding that COUNT/EXACTLY is mandatory for this command form.","solutions":["Call .count(n, order) or .exactly(n, order) on the LMoveMParams before executing the command","If you don't want a count, use the command overload that takes no LMoveMParams","Check factory/builder code paths to ensure one of the two selector methods is always invoked"],"exampleFix":"// before\nLMoveMParams params = new LMoveMParams();\njedis.lmpop(keys, LeftRight.LEFT, params);\n// after\nLMoveMParams params = new LMoveMParams().count(3, ListMoveOrder.OBO);\njedis.lmpop(keys, LeftRight.LEFT, params);","handlingStrategy":"validation","validationCode":"if (params == null || !hasSelector(params)) params = new LMoveMParams().count(n, ListMoveOrder.OBO);","typeGuard":null,"tryCatchPattern":"try {\n  jedis.lmpop(keys, LeftRight.LEFT, params);\n} catch (IllegalArgumentException e) {\n  jedis.lmpop(keys, LeftRight.LEFT, new LMoveMParams().count(1, ListMoveOrder.OBO));\n}","preventionTips":["Always build LMoveMParams with count(...) or exactly(...) as the first call","Centralize params construction in one factory method","Don't pass bare new LMoveMParams() to the command"],"tags":["jedis","lmove","missing-required-argument","illegal-argument"],"backgroundTag":"missing-required-argument","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"}