{"record":{"id":"4e95e38763595c80","repo":"apache/iceberg","slug":"no-more-scan-tasks-available","errorCode":null,"errorMessage":"No more scan tasks available","messagePattern":"No more scan tasks available","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/ScanTaskIterable.java","lineNumber":270,"sourceCode":"          }\n        } catch (InterruptedException e) {\n          Thread.currentThread().interrupt();\n          shutdown.set(true);\n        }\n      }\n\n      RuntimeException workerFailure = failure.get();\n      if (workerFailure != null) {\n        throw workerFailure;\n      }\n\n      return hasNext;\n    }\n\n    @Override\n    public FileScanTask next() {\n      if (!hasNext()) {\n        throw new NoSuchElementException(\"No more scan tasks available\");\n      }\n      FileScanTask result = nextTask;\n      nextTask = null;\n      return result;\n    }\n\n    @Override\n    public void close() {\n      shutdown.set(true);\n      LOG.info(\n          \"ScanTasksIterator is closing. Clearing {} queued tasks and {} plan tasks.\",\n          taskQueue.size(),\n          planTasks.size());\n      taskQueue.clear();\n      planTasks.clear();\n    }\n  }\n}","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/ScanTaskIterable.java#L252-L288","documentation":"Standard NoSuchElementException thrown by the FileScanTaskIterator's next() when next() is called after the iterator is exhausted. It exists to give a clearer message than the default no-args NoSuchElementException.","triggerScenarios":"Calling next() on a ScanTaskIterable iterator without a preceding true hasNext() — e.g. looping twice over a single-element iterator, or calling next() twice past the end.","commonSituations":"Bugs in code that iterates scan tasks without hasNext guards; consumer pipelines that over-advance iterators; reusing exhausted iterators instead of requesting new ones.","solutions":["Guard every next() call with hasNext()","Use a for-each loop instead of manual iterator calls","Re-acquire the iterator (re-run tasks()) if you need to iterate again","Don't store/iterate the iterator after consuming it"],"exampleFix":"// before\nCloseableIterator<FileScanTask> it = tasks.iterator();\nFileScanTask t1 = it.next();\nFileScanTask t2 = it.next(); // throws when exhausted\n// after\nwhile (it.hasNext()) {\n  FileScanTask t = it.next();\n}\n// or: for (FileScanTask t : tasks) { ... }","handlingStrategy":"type-guard","validationCode":"// always check before advancing\nif (iterator.hasNext()) { iterator.next(); }","typeGuard":"boolean safeNext(Iterator<FileScanTask> it) {\n  if (!it.hasNext()) return false;\n  it.next();\n  return true;\n}","tryCatchPattern":"try { task = it.next(); } catch (NoSuchElementException e) {\n  task = null; // or break the loop\n}","preventionTips":["Always gate next() with hasNext()","Prefer for-each loops over manual iterators","Never reuse an exhausted iterator; call tasks() again"],"tags":["iterator","scan-tasks","nosuchelement"],"backgroundTag":"empty-result-set","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}