krahets/hello-algo · error · IndexError

Deque is empty

Error message

Deque is empty

What it means

Raised by LinkedListDeque#pop (en/codes/ruby/chapter_stack_and_queue/linkedlist_deque.rb:70) when the deque is empty. pop(is_front) unlinks either @front or @rear; the guard rejects the operation because there is no node to unlink when size == 0. The public pop_first/pop_last delegate here, so both surface the same message.

Source

Thrown at en/codes/ruby/chapter_stack_and_queue/linkedlist_deque.rb:70

      node.prev = @rear
      @rear = node # Update tail node
    end
    @size += 1 # Update queue length
  end

  ### Enqueue at front ###
  def push_first(num)
    push(num, true)
  end

  ### Enqueue at rear ###
  def push_last(num)
    push(num, false)
  end

  ### Dequeue operation ###
  def pop(is_front)
    raise IndexError, 'Deque is empty' if is_empty?

    # Temporarily store head node value
    if is_front
      val = @front.val # Delete head node
      # Delete head node
      fnext = @front.next
      unless fnext.nil?
        fnext.prev = nil
        @front.next = nil
      end
      @front = fnext # Update head node
    # Temporarily store tail node value
    else
      val = @rear.val # Delete tail node
      # Update tail node
      rprev = @rear.prev
      unless rprev.nil?
        rprev.next = nil

View on GitHub (pinned to 69932aed18)

Solutions

  1. Check deque.is_empty? before pop_first/pop_last.
  2. Verify deque.size >= 1 (or >= 2 for paired pops) before removing.
  3. Rescue IndexError around the pop and treat empty as the loop's exit condition.

Example fix

# before
while true
  deque.pop_last # raises once drained
end

# after
until deque.is_empty?
  deque.pop_last
end
Defensive patterns

Strategy: validation

Validate before calling

deque.pop_first unless deque.is_empty?

Type guard

def deque_nonempty?(d); d.respond_to?(:is_empty?) && !d.is_empty?; end

Try / catch

begin
  deque.pop_last
rescue IndexError
  nil
end

Prevention

When it happens

Trigger: Calling deque.pop_first or deque.pop_last when deque.size == 0. Occurs after removing every node, or immediately after LinkedListDeque.new with no push_first/push_last calls.

Common situations: A sliding-window or palindrome/buffer routine that pops both ends and overshoots; a deque used as a work-list where every task is consumed; test code that pops in pairs without checking size.

Related errors


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