{"record":{"id":"18999bbf83ba201e","repo":"stanfordnlp/CoreNLP","slug":"filter-next-called-with-no-next","errorCode":null,"errorMessage":"Filter .next() called with no next","messagePattern":"Filter \\.next\\(\\) called with no next","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/Iterables.java","lineNumber":84,"sourceCode":"      final Iterable<T> iterable, final Predicate<T> accept) {\n\n    return new Iterable<T>() {\n      public Iterator<T> iterator() {\n        return new Iterator<T>() {\n          Iterator<T> inner = iterable.iterator();\n\n          boolean queued = false;\n          T next = null;\n\n          public boolean hasNext() {\n            prepare();\n            return queued;\n          }\n\n          public T next() {\n            prepare();\n            if (!queued) {\n              throw new RuntimeException(\"Filter .next() called with no next\");\n            }\n            T rv = next;\n            next = null;\n            queued = false;\n            return rv;\n          }\n\n          public void prepare() {\n            if (queued) {\n              return;\n            }\n\n            while (inner.hasNext()) {\n              T next = inner.next();\n              if (accept.test(next)) {\n                this.next = next;\n                this.queued = true;\n                return;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/Iterables.java#L66-L102","documentation":"The anonymous Filter iterator in Iterables.wrap/transform caches one lookahead element. next() calls prepare() to fill that cache; if no element matched the filter predicate, there is nothing to return and the iterator throws rather than returning null.","triggerScenarios":"Calling next() on a Filter iterator after hasNext() returned false, or calling next() repeatedly/concurrently such that the single-slot cache was already consumed (queued == false).","commonSituations":"Not checking hasNext() in a loop, calling next() twice expecting two elements when only one passed the predicate, or sharing one iterator between threads.","solutions":["Always guard calls with if (iterator.hasNext()) before next()","Use a for-each loop instead of manual next() calls","Create a fresh iterator per thread instead of sharing","Check the filter predicate if you expect elements but hasNext() is false"],"exampleFix":"// before\nT v = filteredIterator.next();\n// after\nif (filteredIterator.hasNext()) {\n  T v = filteredIterator.next();\n}","handlingStrategy":"type-guard","validationCode":"// check before consuming\nboolean has = filterIterator.hasNext();\nif (has) { T v = filterIterator.next(); }","typeGuard":"static <T> java.util.Optional<T> nextIfPresent(java.util.Iterator<T> it) {\n  return it.hasNext() ? java.util.Optional.of(it.next()) : java.util.Optional.empty();\n}","tryCatchPattern":"try {\n  T v = filterIterator.next();\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"no next\")) {\n    v = null; // iterator exhausted\n  } else { throw e; }\n}","preventionTips":["Always call hasNext() before next()","Use for-each instead of manual iteration","Do not share iterators across threads","Remember filter iterators only buffer one element"],"tags":["iterator","java-collections","misuse"],"backgroundTag":"iterator-next-without-hasnext","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"}