krahets/hello-algo · error · RangeError
Heap is empty.
Error message
Heap is empty.
What it means
Thrown by MaxHeap.pop when the heap is empty. pop swaps the root with the last element, removes it, and re-heapifies; with zero elements those steps are meaningless and would return undefined, so the method throws a RangeError to signal the precondition violation.
Source
Thrown at en/codes/typescript/chapter_heap/my_heap.ts:84
/* Starting from node i, heapify from bottom to top */
private siftUp(i: number): void {
while (true) {
// Get parent node of node i
const p = this.parent(i);
// When "crossing root node" or "node needs no repair", end heapify
if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;
// Swap two nodes
this.swap(i, p);
// Loop upward heapify
i = p;
}
}
/* Element exits heap */
public pop(): number {
// Handle empty case
if (this.isEmpty()) throw new RangeError('Heap is empty.');
// Delete node
this.swap(0, this.size() - 1);
// Remove node
const val = this.maxHeap.pop();
// Return top element
this.siftDown(0);
// Return heap top element
return val;
}
/* Starting from node i, heapify from top to bottom */
private siftDown(i: number): void {
while (true) {
// If node i is largest or indices l, r are out of bounds, no need to continue heapify, break
const l = this.left(i),
r = this.right(i);
let ma = i;
if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;View on GitHub (pinned to 69932aed18)
Solutions
- Guard every pop with isEmpty() (or size() > 0) first.
- Use a while (!heap.isEmpty()) loop for draining.
- Return an Option/sentinel from a wrapper instead of letting pop throw.
Example fix
// before const top = heap.pop(); // throws if empty // after const top = heap.isEmpty() ? undefined : heap.pop();
Defensive patterns
Strategy: validation
Validate before calling
const top = heap.isEmpty() ? undefined : heap.pop();
Type guard
function hasElements(h) { return typeof h.isEmpty === 'function' && !h.isEmpty(); } Try / catch
try { return heap.pop(); }
catch (e) { if (!(e instanceof RangeError)) throw e; return undefined; } Prevention
- Always pair pop with an isEmpty() check.
- Drain with while (!heap.isEmpty()).
- Wrap pop in a helper that returns an Option for pipeline safety.
When it happens
Trigger: Calling pop on a freshly constructed heap with no inserts; calling pop more times than elements were pushed; interleaving pop with failed pushes so the count is lower than expected.
Common situations: Drain loops that do not check isEmpty; priority-queue consumers that pop on every tick regardless of fill level; off-by-one in loop counters.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/58cc01ee60cb094c.
Report an issue: GitHub.