{"record":{"id":"25e73e3c9b96f58f","repo":"pinpoint-apm/pinpoint","slug":"illegalstateexception-25e73e","errorCode":null,"errorMessage":"IllegalStateException","messagePattern":"IllegalStateException","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/concurrent/jsr166/ConcurrentWeakHashMap.java","lineNumber":1209,"sourceCode":"            return false;\n        }\n\n        HashEntry<K,V> nextEntry() {\n            do {\n                if (nextEntry == null)\n                    throw new NoSuchElementException();\n\n                lastReturned = nextEntry;\n                currentKey = lastReturned.keyRef.get();\n                advance();\n            } while (currentKey == null); // Skip GC'd keys\n\n            return lastReturned;\n        }\n\n        public void remove() {\n            if (lastReturned == null)\n                throw new IllegalStateException();\n            ConcurrentWeakHashMap.this.remove(currentKey);\n            lastReturned = null;\n        }\n    }\n\n    final class KeyIterator\n            extends HashIterator\n            implements Iterator<K>, Enumeration<K>\n    {\n        public K next()        { return super.nextEntry().keyRef.get(); }\n        public K nextElement() { return super.nextEntry().keyRef.get(); }\n    }\n\n    final class ValueIterator\n            extends HashIterator\n            implements Iterator<V>, Enumeration<V>\n    {\n        public V next()        { return super.nextEntry().value; }","sourceCodeStart":1191,"sourceCodeEnd":1227,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/concurrent/jsr166/ConcurrentWeakHashMap.java#L1191-L1227","documentation":"Iterator.remove() throws IllegalStateException when lastReturned is null, meaning remove() was called before any next() call, twice in a row, or after the entry was already removed. Each next() must be paired with at most one remove().","triggerScenarios":"it.remove() as the first call on a fresh iterator; calling remove() twice after a single next(); calling remove() after a previous remove() set lastReturned = null.","commonSituations":"Conditional cleanup loops that call remove() outside the per-element branch; copy-pasted remove logic executed on an unused iterator.","solutions":["Only call remove() immediately after a successful next(), once per element","Move the remove() call inside the loop body guarded by the per-element condition","Remove via map.remove(key) directly instead of the iterator when state is unclear"],"exampleFix":"// before\nfor (K k : map.keySet()) {\n    if (expired(k)) map.remove(k);\n}\nit.remove(); // stray call\n// after\nIterator<K> it = map.keySet().iterator();\nwhile (it.hasNext()) {\n    K k = it.next();\n    if (expired(k)) { it.remove(); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { it.remove(); } catch (IllegalStateException e) { /* remove without preceding next(): fix loop structure */ }","preventionTips":["Pair every remove() with exactly one preceding next() call in the same loop iteration","Never call it.remove() outside the loop body","Prefer collecting keys then map.removeAll(collected) for bulk cleanup"],"tags":["java","concurrency","iterator","illegal-state"],"backgroundTag":"iterator-remove-without-next","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}