{"record":{"id":"73d05bb221c157c1","repo":"ReactiveX/RxJava","slug":"read-only-iterator-73d05b","errorCode":null,"errorMessage":"Read only iterator","messagePattern":"Read only iterator","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"src/main/java/io/reactivex/rxjava4/internal/operators/flowable/BlockingFlowableNext.java","lineNumber":128,"sourceCode":"\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\n        @Override\n        public void onError(Throwable e) {\n            RxJavaPlugins.onError(e);\n        }\n\n        @Override","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/ReactiveX/RxJava/blob/a8ab5356143f37a8f1dd6d76c79191bec5fa343b/src/main/java/io/reactivex/rxjava4/internal/operators/flowable/BlockingFlowableNext.java#L110-L146","documentation":"Thrown by Iterator.remove() from Flowable.blockingNext() when removal is attempted. The blockingNext() iterator yields Notifications one at a time from a push-based source, so it has no mutable backing store and remove() is permanently unsupported. The message 'Read only iterator' documents this intentional contract.","triggerScenarios":"Calling it.remove() on the iterator from Flowable.blockingNext().iterator(); feeding that iterator into a generic processor that invokes remove() after consumption; manual loop template that includes remove().","commonSituations":"Reusing imperative collection-walking code that paired next() with remove(); integration with a third-party library that calls remove() to drain iterators; forgetting that blocking RxJava iterators are views, not collections.","solutions":["Delete the it.remove() call; these iterators are read-only and cannot mutate the source.","If you must discard consumed elements, collect kept items into a new list instead of removing from the iterator.","Wrap the iterator in a forwarding Iterator whose remove() is a no-op if a component requires the method to exist.","Filter upstream with Flowable.filter(...) before blockingNext() to shape the data rather than removing downstream."],"exampleFix":"// before\nIterator<T> it = flowable.blockingNext().iterator();\nwhile (it.hasNext()) { T v = it.next(); if (shouldDrop(v)) it.remove(); }\n// after\nList<T> kept = new ArrayList<>();\nIterator<T> it = flowable.blockingNext().iterator();\nwhile (it.hasNext()) { T v = it.next(); if (!shouldDrop(v)) kept.add(v); }","handlingStrategy":"validation","validationCode":"// Read-only iterator: never call remove().\nIterator<T> it = flowable.blockingNext().iterator();\nwhile (it.hasNext()) {\n    T v = it.next();\n    // process v; it.remove() is permanently unsupported\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Recognize blocking RxJava iterators as read-only views of a push source.","Filter upstream (Flowable.filter) instead of removing downstream.","Forward through a no-op remove() wrapper if a dependency calls remove().","Keep consumed items in your own mutable list rather than mutating the iterator."],"tags":["rxjava","iterator","unsupported-operation","blocking","flowable"],"backgroundTag":null,"analyzedSha":"a8ab5356143f37a8f1dd6d76c79191bec5fa343b","analyzedAt":"2026-08-13T23:25:30.069Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}