{"record":{"id":"7e4fa2710ecf69a9","repo":"apache/hadoop","slug":"no-more-items-in-iterator","errorCode":null,"errorMessage":"No more items in iterator","messagePattern":"No more items in iterator","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java","lineNumber":434,"sourceCode":"    return new RemoteIterator<FileStatus>() {\n      private DirectoryEntries entries = listStatusBatch(p, null);\n      private int index = 0;\n\n      @Override\n      public boolean hasNext() {\n        return index < entries.getEntries().length || entries.hasMore();\n      }\n\n      private void fetchMore() throws IOException {\n        byte[] token = entries.getToken();\n        entries = listStatusBatch(p, token);\n        index = 0;\n      }\n\n      @Override\n      public FileStatus next() throws IOException {\n        if (!hasNext()) {\n          throw new NoSuchElementException(\"No more items in iterator\");\n        } else {\n          if (index == entries.getEntries().length) {\n            fetchMore();\n            if (!hasNext()) {\n              throw new NoSuchElementException(\"No more items in iterator\");\n            }\n          }\n\n          return entries.getEntries()[index++];\n        }\n      }\n    };\n  }\n\n  public static long dateToLong(final Date date) {\n    return date == null ? 0L : date.getTime();\n  }\n","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java#L416-L452","documentation":"The listing iterator returned by listStatus(f, recursive) throws NoSuchElementException from next() when there are no more entries. This is standard Java iterator contract enforcement: next() was called after hasNext() returned false (either initially, or after fetching the next batch via listStatusBatch came back empty).","triggerScenarios":"Calling it.next() without a preceding it.hasNext() check, or a loop like while(true) { it.next(); } on the iterator returned by RawFileSystem.listStatus(Path, boolean).","commonSituations":"Hand-rolled pagination loops that assume a fixed batch size; code converted from array-based listStatus() to the recursive iterator without preserving the hasNext() guard; streaming consumers that call next() then handle NoSuchElementException as flow control.","solutions":["Always guard next() with hasNext(): while (it.hasNext()) { ... it.next(); }","Prefer the array API listStatus(f) or Iterators.toArray(...) which handles exhaustion internally","If you already guard and still hit it (empty batch after hasMore()=true), report it as a paging bug in hadoop-tos with the token/batch details"],"exampleFix":"// before\nIterator<RawFileStatus> it = fs.listStatus(dir, true);\nwhile (true) { RawFileStatus s = it.next(); process(s); } // NoSuchElementException at end\n\n// after\nwhile (it.hasNext()) { RawFileStatus s = it.next(); process(s); }","handlingStrategy":"validation","validationCode":"Iterator<RawFileStatus> it = fs.listStatus(dir, recursive);\nwhile (it.hasNext()) {\n  RawFileStatus s = it.next(); // only call next() when hasNext() just returned true\n  process(s);\n}","typeGuard":null,"tryCatchPattern":"try { s = it.next(); }\ncatch (NoSuchElementException e) { break; } // last resort; prefer hasNext()","preventionTips":["Always pair next() with a same-thread hasNext() check","Use listStatus(f) arrays or Iterators.toArray for bulk loads","Keep iterator usage single-threaded"],"tags":["iterator","nosuchelementexception","listing","iteration-protocol","tos"],"backgroundTag":"iterator-exhausted","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}