{"record":{"id":"d80c2b6d8c379716","repo":"stanfordnlp/CoreNLP","slug":"graph-edge-iterator-exhausted","errorCode":null,"errorMessage":"Graph edge iterator exhausted.","messagePattern":"Graph edge iterator exhausted\\.","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/graph/DirectedMultiGraph.java","lineNumber":567,"sourceCode":"      currentSource = startVertex;\n      Map<V, List<E>> neighbors = source.get(startVertex);\n      if (neighbors != null) {\n        vertexIterator = null;\n        connectionIterator = neighbors.entrySet().iterator();\n      }\n      this.reverseEdges = reverseEdges;\n    }\n\n    @Override\n    public boolean hasNext() {\n      primeIterator();\n      return hasNext;\n    }\n\n    @Override\n    public E next() {\n      if (!hasNext()) {\n        throw new NoSuchElementException(\"Graph edge iterator exhausted.\");\n      }\n      currentEdge = edgeIterator.next();\n      return currentEdge;\n    }\n\n    private void primeIterator() {\n      while (true) {\n        if (edgeIterator != null && edgeIterator.hasNext()) {\n          hasNext = true;  // technically, we shouldn't need to put this here, but let's be safe\n          return;\n        } else if (connectionIterator != null && connectionIterator.hasNext()) {\n          Map.Entry<V, List<E>> nextConnection = connectionIterator.next();\n          edgeIterator = nextConnection.getValue().iterator();\n          currentTarget = nextConnection.getKey();\n        } else if (vertexIterator != null && vertexIterator.hasNext()) {\n          Map.Entry<V, Map<V, List<E>>> nextVertex = vertexIterator.next();\n          connectionIterator = nextVertex.getValue().entrySet().iterator();\n          currentSource = nextVertex.getKey();","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/graph/DirectedMultiGraph.java#L549-L585","documentation":"A NoSuchElementException guard in DirectedMultiGraph's edge iterator: next() was called after hasNext() returned false, i.e. the consumer iterated past the last edge (forward or reverse view) of the graph.","triggerScenarios":"Calling next() on the graph's edge iterator after hasNext() returns false, e.g. looping past the end or calling next() an extra time in a manual iterator loop.","commonSituations":"Manual iterator loops with an off-by-one; calling next() once more to 'consume' a last element; reusing an exhausted iterator instead of getting a fresh one.","solutions":["Use a for-each loop or while(iterator.hasNext()) instead of manual next() calls","Get a fresh iterator from the graph instead of reusing an exhausted one","Guard each next() call with hasNext()"],"exampleFix":"// before\nIterator<E> it = graph.edgeIterator();\nE e1 = it.next(); E e2 = it.next(); // may exhaust\n// after\nfor (E e : graph.getEdgeIterable()) { process(e); }","handlingStrategy":"type-guard","validationCode":"if (iterator.hasNext()) { E e = iterator.next(); }","typeGuard":"boolean available = it.hasNext(); // gate every next() call on this","tryCatchPattern":"try { e = it.next(); } catch (NoSuchElementException e2) { e = null; /* iterator exhausted */ }","preventionTips":["Prefer for-each / iterable APIs over manual iterators","Never call next() more times than hasNext() confirmed","Get a fresh iterator for each traversal"],"tags":["iterator","nosuchelement","graph"],"backgroundTag":"index-out-of-bounds","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}