krahets/hello-algo · error · IndexError
Queue is empty
Error message
Queue is empty
What it means
ArrayQueue.peek raises IndexError('Queue is empty') when _size is zero, blocking the read of self._nums[_front]. Because pop() delegates to peek(), calling pop() on an empty queue surfaces this same exception. The guard enforces that front access is only valid when the queue holds at least one element.
Source
Thrown at en/codes/python/chapter_stack_and_queue/array_queue.py:51
# Calculate rear pointer, points to rear index + 1
# Use modulo operation to wrap rear around to the head after passing the tail of the array
rear: int = (self._front + self._size) % self.capacity()
# Add num to the rear of the queue
self._nums[rear] = num
self._size += 1
def pop(self) -> int:
"""Dequeue"""
num: int = self.peek()
# Front pointer moves one position backward, if it passes the tail, return to the head of the array
self._front = (self._front + 1) % self.capacity()
self._size -= 1
return num
def peek(self) -> int:
"""Access front of the queue element"""
if self.is_empty():
raise IndexError("Queue is empty")
return self._nums[self._front]
def to_list(self) -> list[int]:
"""Return list for printing"""
res = [0] * self.size()
j: int = self._front
for i in range(self.size()):
res[i] = self._nums[(j % self.capacity())]
j += 1
return res
"""Driver Code"""
if __name__ == "__main__":
# Initialize queue
queue = ArrayQueue(10)
# Elements enqueueView on GitHub (pinned to 69932aed18)
Solutions
- Guard single access: `if not queue.is_empty(): head = queue.peek()`.
- Bound drains: `while not queue.is_empty(): x = queue.pop()`.
- Use queue.size() to control counted loops.
- Catch IndexError only when using exception-based flow control deliberately.
Example fix
// before head = queue.peek() # raises if empty // after head = queue.peek() if not queue.is_empty() else None
Defensive patterns
Strategy: validation
Validate before calling
if not queue.is_empty():
head = queue.peek() Type guard
def queue_nonempty(q) -> bool:
return not q.is_empty() Try / catch
try:
head = queue.peek()
except IndexError:
head = None Prevention
- Drive drains with `while not queue.is_empty()`.
- Bound counted loops with size().
- Use a wrapper returning Optional for empty-state consumers.
When it happens
Trigger: Calling peek() or pop() on a freshly constructed queue; popping after the last element was dequeued; drain loops `while True: q.pop()` without an emptiness exit; consumer running ahead of producer.
Common situations: BFS and level-order traversals that dequeue until empty; producer/consumer pacing skew; unguarded counted dequeue loops; test code that pops more than it pushed.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/baa5a00821d649e1.
Report an issue: GitHub.