{"record":{"id":"7fbbd3e9a4c7520e","repo":"dotnet/reactive","slug":"strings-core-heap-empty","errorCode":null,"errorMessage":"Strings_Core.HEAP_EMPTY","messagePattern":"Strings_Core\\.HEAP_EMPTY","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Internal/PriorityQueue.cs","lineNumber":90,"sourceCode":"\n                if (first == index)\n                {\n                    break;\n                }\n\n                // swap index and first\n                (_items[first], _items[index]) = (_items[index], _items[first]);\n                index = first;\n            }\n        }\n\n        public int Count => _size;\n\n        public T Peek()\n        {\n            if (_size == 0)\n            {\n                throw new InvalidOperationException(Strings_Core.HEAP_EMPTY);\n            }\n\n            return _items[0].Value;\n        }\n\n        private void RemoveAt(int index)\n        {\n            _items[index] = _items[--_size];\n            _items[_size] = default;\n\n            if (Percolate(index) == index)\n            {\n                Heapify(index);\n            }\n\n            if (_size < _items.Length / 4)\n            {\n                var temp = _items;","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Internal/PriorityQueue.cs#L72-L108","documentation":"Peek() on System.Reactive's internal PriorityQueue throws InvalidOperationException when the queue is empty (_size == 0). The queue requires at least one scheduled item to inspect. The library treats peeking into an empty priority queue as a programming error rather than returning a default value.","triggerScenarios":"Calling PriorityQueue<T>.Peek() when _size == 0, i.e. before any Enqueue or after all items have been dequeued/removed. The index also surfaces via scheduled work algorithms that Peek before checking Count.","commonSituations":"Custom scheduler implementations or tests that call Peek on a freshly created queue; race conditions where another thread dequeued the last item between a Count check and Peek (Count/Peek not atomic).","solutions":["Check Count > 0 before calling Peek, or use TryPeek-style logic (Count check plus Peek in one thread-safe step).","If queue may be consumed concurrently, synchronize access with a lock around Count/Peek/Dequeue calls.","Wrap Peek in try-catch for InvalidOperationException only if racing behavior is tolerated and treated as 'queue went empty'."],"exampleFix":"// before\nvar next = queue.Peek();\n// after\nif (queue.Count == 0) return;\nvar next = queue.Peek();","handlingStrategy":"validation","validationCode":"if (queue.Count > 0) { var next = queue.Peek(); ... }","typeGuard":null,"tryCatchPattern":"try { next = queue.Peek(); } catch (InvalidOperationException) { /* queue became empty */ }","preventionTips":["Always check Count before Peek on a PriorityQueue.","Synchronize Count+Peek with a lock when multiple threads mutate the queue.","Prefer TryDequeue/TryPeek-style APIs where available."],"tags":["invalid-operation","empty-collection","scheduler"],"backgroundTag":"empty-required-field","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}