TheAlgorithms/Java · error · IllegalStateException

MinPriorityQueue is empty. Cannot delete.

Error message

MinPriorityQueue is empty. Cannot delete.

What it means

Thrown by MinPriorityQueue.delete() when isEmpty() returns true. delete moves the last element to the root, decrements size, and re-heapifies, so an empty queue would underflow the size counter and read heap[0]. The guard blocks the underflow.

Source

Thrown at src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java:147

            // Swap with the smallest child
            int temp = this.heap[k];
            this.heap[k] = this.heap[minIndex];
            this.heap[minIndex] = temp;

            k = minIndex; // Move down to the smallest child
        }
    }

    /**
     * Deletes and returns the highest priority value (the minimum) from the queue.
     *
     * @return the minimum value from the queue
     * @throws IllegalStateException if the queue is empty
     */
    public int delete() {
        if (isEmpty()) {
            throw new IllegalStateException("MinPriorityQueue is empty. Cannot delete.");
        }
        int min = this.heap[1];
        this.heap[1] = this.heap[this.size]; // Move last element to the root
        this.size--;
        this.sink();
        return min;
    }
}

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Loop while `!pq.isEmpty()` rather than a fixed count.
  2. Guard each delete with an isEmpty check.
  3. Track insertions and bound deletions to that count.
  4. Catch IllegalStateException at the consumer and treat it as end-of-stream.

Example fix

// before
while (count-- > 0) { int m = pq.delete(); }

// after
while (!pq.isEmpty()) {
    int m = pq.delete();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!pq.isEmpty()) {
    return pq.delete();
}

Try / catch

try {
    return pq.delete();
} catch (IllegalStateException e) {
    // queue empty — end of stream
    return OptionalInt.empty();
}

Prevention

When it happens

Trigger: Calling delete more times than insert. Draining a queue in a fixed-count loop larger than the population. Deleting from a queue whose producer has not started.

Common situations: Loop bound computed from a different source than actual insertions. Consumer running ahead of producer. Off-by-one in drain logic.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/3fbc4c5139f3f017. Report an issue: GitHub.