{"record":{"id":"ef87d03e868d4d70","repo":"ReactiveX/RxJava","slug":"read-only-iterator-ef87d0","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/observable/BlockingObservableMostRecent.java","lineNumber":115,"sourceCode":"                    if (buf == null) {\n                        buf = value;\n                    }\n                    if (NotificationLite.isComplete(buf)) {\n                        throw new NoSuchElementException();\n                    }\n                    if (NotificationLite.isError(buf)) {\n                        throw ExceptionHelper.wrapOrThrow(NotificationLite.getError(buf));\n                    }\n                    return NotificationLite.getValue(buf);\n                }\n                finally {\n                    buf = null;\n                }\n            }\n\n            @Override\n            public void remove() {\n                throw new UnsupportedOperationException(\"Read only iterator\");\n            }\n        }\n    }\n}\n","sourceCodeStart":97,"sourceCodeEnd":120,"githubUrl":"https://github.com/ReactiveX/RxJava/blob/a8ab5356143f37a8f1dd6d76c79191bec5fa343b/src/main/java/io/reactivex/rxjava4/internal/operators/observable/BlockingObservableMostRecent.java#L97-L120","documentation":"Thrown by Iterator.remove() on the iterator from Observable.blockingMostRecent(). The iterator replays the most recently emitted Notification (value, completion, or error) and is a read-only view, so remove() always throws UnsupportedOperationException(\"Read only iterator\"). There is no underlying collection to mutate.","triggerScenarios":"Calling it.remove() on the iterator from observable.blockingMostRecent(initial).iterator(); a generic consumer that invokes remove() during drain; ported imperative loop with a remove() step.","commonSituations":"Legacy collection-processing code that paired next() with remove(); a utility library that calls remove() on any iterator; misreading blockingMostRecent() as a queue you can shrink.","solutions":["Remove the it.remove() call; this iterator is read-only.","Filter the source upstream with Observable.filter(...) to exclude items before blocking iteration.","Maintain your own mutable collection of retained items instead of mutating the iterator.","Delegate through a no-op remove() wrapper if a dependency requires the method."],"exampleFix":"// before\nIterator<T> it = observable.blockingMostRecent(initial).iterator();\nwhile (it.hasNext()) { T v = it.next(); if (drop(v)) it.remove(); }\n// after\nIterator<T> it = observable.blockingMostRecent(initial).iterator();\nList<T> kept = new ArrayList<>();\nwhile (it.hasNext()) { T v = it.next(); if (!drop(v)) kept.add(v); }","handlingStrategy":"validation","validationCode":"// Read-only iterator: never call remove().\nIterator<T> it = observable.blockingMostRecent(initial).iterator();\nwhile (it.hasNext()) {\n    T v = it.next();\n    // process v; it.remove() is unsupported\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat blockingMostRecent() iterators as unmodifiable views.","Filter upstream with Observable.filter(...) to exclude items.","Maintain your own mutable collection of retained items.","Use a no-op remove() forwarder if a dependency mandates remove()."],"tags":["rxjava","iterator","unsupported-operation","blocking","observable"],"backgroundTag":null,"analyzedSha":"a8ab5356143f37a8f1dd6d76c79191bec5fa343b","analyzedAt":"2026-08-13T23:25:30.069Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}