{"record":{"id":"81777e6311817a5c","repo":"ReactiveX/RxJava","slug":"no-more-elements","errorCode":null,"errorMessage":"No more elements","messagePattern":"No more elements","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"warning","filePath":"src/main/java/io/reactivex/rxjava4/internal/operators/flowable/BlockingFlowableNext.java","lineNumber":122,"sourceCode":"            } catch (InterruptedException e) {\n                subscriber.dispose();\n                error = e;\n                throw ExceptionHelper.wrapOrThrow(e);\n            }\n        }\n\n        @Override\n        public T next() {\n            if (error != null) {\n                // If any error has already been thrown, throw it again.\n                throw ExceptionHelper.wrapOrThrow(error);\n            }\n            if (hasNext()) {\n                isNextConsumed = true;\n                return next;\n            }\n            else {\n                throw new NoSuchElementException(\"No more elements\");\n            }\n        }\n\n        @Override\n        public void remove() {\n            throw new UnsupportedOperationException(\"Read only iterator\");\n        }\n    }\n\n    static final class NextSubscriber<T> extends DisposableSubscriber<Notification<T>> {\n        private final BlockingQueue<Notification<T>> buf = new ArrayBlockingQueue<>(1);\n        final AtomicInteger waiting = new AtomicInteger();\n\n        @Override\n        public void onComplete() {\n            // ignore\n        }\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/ReactiveX/RxJava/blob/a8ab5356143f37a8f1dd6d76c79191bec5fa343b/src/main/java/io/reactivex/rxjava4/internal/operators/flowable/BlockingFlowableNext.java#L104-L140","documentation":"Thrown by Iterator.next() from Flowable.blockingNext() when the upstream has completed and there is no further item to deliver. It signals a normal terminal condition of the blocking iterator: next() was called after the source Flowable signalled onComplete (or after the last buffered Notification was consumed and hasNext() is now false).","triggerScenarios":"Calling next() without guarding hasNext() after the source completes; a loop that assumes N items but the source emitted fewer; the upstream completes immediately (e.g. Flowable.empty()) and next() is invoked once.","commonSituations":"Parsing/flattening a finite stream via blockingNext() and miscounting expected elements; an upstream that completes early due to a filter that removes all elements; off-by-one in a manual index counter driving next() calls.","solutions":["Always guard next() with hasNext(): while (it.hasNext()) { T v = it.next(); ... }","Verify the upstream Flowable emits the expected count (use test() assertions) before relying on blocking iteration.","If an empty result is legitimate, catch NoSuchElementException and supply a default instead of treating it as a failure.","Add an isEmpty check via Flowable.isEmpty().blockingGet() before iterating if a non-empty contract is required."],"exampleFix":"// before\nIterator<T> it = flowable.blockingNext().iterator();\nT first = it.next(); // throws if source empty\n// after\nIterator<T> it = flowable.blockingNext().iterator();\nif (!it.hasNext()) { return defaultValue; }\nT first = it.next();","handlingStrategy":"try-catch","validationCode":"// Validate non-empty before consuming the blocking next-iterator.\nboolean nonEmpty = flowable.isEmpty().blockingGet(); // false => has at least one\nIterator<T> it = flowable.blockingNext().iterator();\nif (!it.hasNext()) { /* source is empty/complete */ }","typeGuard":null,"tryCatchPattern":"Iterator<T> it = flowable.blockingNext().iterator();\nT value;\nif (it.hasNext()) {\n    value = it.next();\n} else {\n    // handle terminal/empty state\n    value = defaultValue;\n}\n// Alternatively, only if a default cannot be structured in:\ntry {\n    while (it.hasNext()) { T v = it.next(); /* consume */ }\n} catch (NoSuchElementException e) {\n    // safe: loop is hasNext-guarded, but guard against stray next() calls\n}","preventionTips":["Always guard Iterator.next() with hasNext() and stop when it returns false.","Use Flowable.isEmpty().blockingGet() to pre-check a non-empty contract.","Assert expected emission counts with test() before relying on blocking iteration.","Prefer a default-supplying accessor when an empty source is legitimate."],"tags":["rxjava","nosuchelement","blocking","flowable","iterator","terminal"],"backgroundTag":null,"analyzedSha":"a8ab5356143f37a8f1dd6d76c79191bec5fa343b","analyzedAt":"2026-08-13T23:25:30.069Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}