{"record":{"id":"ac7b8971f22f22a3","repo":"redis/jedis","slug":"ts-nrange-ts-nrevrange-require-at-least-one-key","errorCode":null,"errorMessage":"TS.NRANGE/TS.NREVRANGE require at least one key","messagePattern":"TS\\.NRANGE/TS\\.NREVRANGE require at least one key","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/CommandObjects.java","lineNumber":4868,"sourceCode":"\n  public final CommandObject<List<TSElement>> tsNRevRange(String[] keys, long fromTimestamp, long toTimestamp) {\n    checkNRangeKeys(keys);\n    return new CommandObject<>(commandArguments(TimeSeriesCommand.NREVRANGE).add(keys.length)\n        .keys((Object[]) keys).add(fromTimestamp).add(toTimestamp),\n        TimeSeriesBuilderFactory.TIMESERIES_PIVOT_ELEMENT_LIST);\n  }\n\n  public final CommandObject<List<TSElement>> tsNRevRange(String[] keys, TSNRangeParams nrangeParams) {\n    checkNRangeKeys(keys);\n    nrangeParams.validateAggregationForKeys(keys.length);\n    return new CommandObject<>(commandArguments(TimeSeriesCommand.NREVRANGE).add(keys.length)\n        .keys((Object[]) keys).addParams(nrangeParams),\n        TimeSeriesBuilderFactory.TIMESERIES_PIVOT_ELEMENT_LIST);\n  }\n\n  private static void checkNRangeKeys(String[] keys) {\n    if (keys == null || keys.length == 0) {\n      throw new IllegalArgumentException(\"TS.NRANGE/TS.NREVRANGE require at least one key\");\n    }\n  }\n\n  public final CommandObject<Map<String, TSMRangeElements>> tsMRange(long fromTimestamp, long toTimestamp, String... filters) {\n    return new CommandObject<>(commandArguments(TimeSeriesCommand.MRANGE).add(fromTimestamp)\n        .add(toTimestamp).add(TimeSeriesKeyword.FILTER).addObjects((Object[]) filters),\n        getTimeseriesMultiRangeResponseBuilder());\n  }\n\n  public final CommandObject<Map<String, TSMRangeElements>> tsMRange(TSMRangeParams multiRangeParams) {\n    return new CommandObject<>(commandArguments(TimeSeriesCommand.MRANGE)\n        .addParams(multiRangeParams), getTimeseriesMultiRangeResponseBuilder());\n  }\n\n  public final CommandObject<Map<String, TSMRangeElements>> tsMRevRange(long fromTimestamp, long toTimestamp, String... filters) {\n    return new CommandObject<>(commandArguments(TimeSeriesCommand.MREVRANGE).add(fromTimestamp)\n        .add(toTimestamp).add(TimeSeriesKeyword.FILTER).addObjects((Object[]) filters),\n        getTimeseriesMultiRangeResponseBuilder());","sourceCodeStart":4850,"sourceCodeEnd":4886,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/CommandObjects.java#L4850-L4886","documentation":"checkNRangeKeys() guards the TimeSeries TS.NRANGE/TS.NREVRANGE command objects: these multi-key commands require at least one key. An empty or null key array cannot form a valid server command, so IllegalArgumentException is thrown client-side.","triggerScenarios":"Calling the tsNRange/tsNRevRange CommandObjects methods with a null String[] or a zero-length array, e.g. tsNRange(from, to, new String[0]) or spreading an empty collection.","commonSituations":"Passing a dynamically built key list that ended up empty (no keys matched a filter upstream); calling the varargs method with no keys; forgetting that varargs spread of an empty list yields an empty array.","solutions":["Check keys != null && keys.length > 0 before invoking tsNRange/tsNRevRange","Guard the upstream key-collection logic so at least one key is always present","If keys may legitimately be empty, skip the call instead of issuing the command"],"exampleFix":"// before\nts.tsNRange(from, to, keys); // keys may be empty\n// after\nif (keys != null && keys.length > 0) {\n  ts.tsNRange(from, to, keys);\n}","handlingStrategy":"validation","validationCode":"if (keys == null || keys.length == 0) { throw new IllegalStateException(\"tsNRange requires at least one key\"); }","typeGuard":"static boolean hasKeys(String[] k) { return k != null && k.length > 0; }","tryCatchPattern":"try { ts.tsNRange(from, to, keys); } catch (IllegalArgumentException e) { log.warn(\"skipping NRANGE: no keys\"); }","preventionTips":["Check upstream key collection is non-empty before calling","Avoid spreading possibly-empty lists into varargs","Skip the command entirely when no keys exist"],"tags":["jedis","timeseries","argument-validation"],"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"}