{"record":{"id":"0cefd541496f461c","repo":"stanfordnlp/CoreNLP","slug":"array-must-be-sorted","errorCode":null,"errorMessage":"Array must be sorted!","messagePattern":"Array must be sorted!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/ArrayUtils.java","lineNumber":40,"sourceCode":"  private static final Redwood.RedwoodChannels log = Redwood.channels(ArrayUtils.class);\n\n  /**\n   * Should not be instantiated\n   */\n  private ArrayUtils() {}\n\n  public static byte[] gapEncode(int[] orig) {\n    List<Byte> encodedList = gapEncodeList(orig);\n    byte[] arr = new byte[encodedList.size()];\n    int i = 0;\n    for (byte b : encodedList) { arr[i++] = b; }\n    return arr;\n  }\n\n  public static List<Byte> gapEncodeList(int[] orig) {\n    for (int i = 1; i < orig.length; i++) {\n      if (orig[i] < orig[i-1]) {\n        throw new IllegalArgumentException(\"Array must be sorted!\");\n      }\n    }\n\n    List<Byte> bytes = new ArrayList<>();\n\n    int index = 0;\n    int prevNum = 0;\n    byte currByte = 0 << 8;\n\n    for (int f : orig) {\n      String n = (f == prevNum ? \"\" : Integer.toString(f-prevNum, 2));\n      for (int ii = 0; ii < n.length(); ii++) {\n        if (index == 8) {\n          bytes.add(currByte);\n          currByte = 0 << 8;\n          index = 0;\n        }\n        currByte <<= 1;","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/ArrayUtils.java#L22-L58","documentation":"ArrayUtils.gapEncodeList computes gap encoding of an int array, which is only well-defined for monotonically non-decreasing sequences (each gap must be non-negative). It scans the array and throws IllegalArgumentException('Array must be sorted!') if any element is smaller than its predecessor.","triggerScenarios":"Calling ArrayUtils.gapEncodeList(int[] orig) where for some i>0, orig[i] < orig[i-1], i.e. the array contains a decreasing pair; also triggered transitively via encodedList on unsorted input.","commonSituations":"Passing positions/docIDs that were not sorted because they came from a HashMap iteration order; appending new items to an encoded list without re-sorting; assuming gapEncodeList sorts for you (it validates but does not sort).","solutions":["Sort the input array first with Arrays.sort(orig) before calling gapEncodeList.","If you must preserve the original order, sort a copy: int[] sorted = orig.clone(); Arrays.sort(sorted); gapEncodeList(sorted).","Pre-validate with a loop or IntStream check that no element is smaller than the previous one, and handle the unsorted case explicitly."],"exampleFix":"// before\nList<Byte> encoded = ArrayUtils.gapEncodeList(docIds); // docIds unsorted\n// after\nint[] sorted = docIds.clone();\nArrays.sort(sorted);\nList<Byte> encoded = ArrayUtils.gapEncodeList(sorted);","handlingStrategy":"validation","validationCode":"for (int i = 1; i < orig.length; i++) {\n  if (orig[i] < orig[i-1]) throw new IllegalArgumentException(\"input to gapEncodeList must be sorted\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  List<Byte> out = ArrayUtils.gapEncodeList(orig);\n} catch (IllegalArgumentException e) {\n  int[] sorted = orig.clone(); Arrays.sort(sorted);\n  List<Byte> out = ArrayUtils.gapEncodeList(sorted);\n}","preventionTips":["Sort arrays (Arrays.sort) immediately before any gap/delta encoding.","Never iterate a HashMap to produce positions for encoding; use sorted structures (TreeMap) or sort first.","Add a unit test asserting monotonicity for encoder inputs."],"tags":["java","arrays","precondition","sorting"],"backgroundTag":"invalid-argument-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}