krahets/hello-algo · error · IndexError

Queue is full

Error message

Queue is full

What it means

ArrayQueue.push raises IndexError('Queue is full') when _size equals capacity(), i.e. the fixed-size circular buffer has no free slot. Because the backing array is preallocated to a fixed capacity, enqueueing beyond it would overwrite the front element; the guard rejects the overflow explicitly. This is an overflow precondition, not a transient backpressure signal.

Source

Thrown at en/codes/python/chapter_stack_and_queue/array_queue.py:32

        self._front: int = 0  # Front pointer, points to the front of the queue element
        self._size: int = 0  # Queue length

    def capacity(self) -> int:
        """Get the capacity of the queue"""
        return len(self._nums)

    def size(self) -> int:
        """Get the length of the queue"""
        return self._size

    def is_empty(self) -> bool:
        """Check if the queue is empty"""
        return self._size == 0

    def push(self, num: int):
        """Enqueue"""
        if self._size == self.capacity():
            raise IndexError("Queue is full")
        # 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():

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check before pushing: `if queue.size() < queue.capacity(): queue.push(x)`.
  2. Size the queue at construction to the worst-case backlog: ArrayQueue(max_concurrent * batch).
  3. Drain (pop) before pushing in tight loops, or apply backpressure to the producer.
  4. If unbounded growth is acceptable, switch to collections.deque instead of the fixed array queue.

Example fix

// before
queue.push(item)  # raises when full
// after
if queue.size() < queue.capacity():
    queue.push(item)
else:
    queue.pop()  # make room / apply backpressure
Defensive patterns

Strategy: validation

Validate before calling

if queue.size() < queue.capacity():
    queue.push(item)
else:
    queue.pop()  # or apply backpressure

Type guard

def queue_has_room(q) -> bool:
    return q.size() < q.capacity()

Try / catch

try:
    queue.push(item)
except IndexError:
    # queue full; shed load, grow, or wait
    handle_overflow(item)

Prevention

When it happens

Trigger: Calling push() more than capacity() times without matching pops; constructing ArrayQueue(capacity) with a too-small capacity for the workload; a producer pushing faster than the consumer pops in a fixed-rate pipeline; ignoring the capacity when sizing the queue.

Common situations: Undersized fixed-capacity queues in bounded-buffer producer/consumer code; batch ingest that exceeds the chosen capacity; porting unbounded collections code to a fixed ring buffer without resizing; forgetting that capacity is set once at construction.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/77a21dc23538b414. Report an issue: GitHub.