deepset-ai/haystack · error · IndexError

peek at empty queue

Error message

peek at empty queue

What it means

FifoPriorityQueue.peek raises IndexError('peek at empty queue') when inspecting the front of an empty queue (utils.py:140). peek is non-destructive but still requires at least one item. Used by pipeline validation and scheduling helpers.

Source

Thrown at haystack/core/pipeline/utils.py:140

        """
        if not self._queue:
            raise IndexError("pop from empty queue")
        priority, _, item = heapq.heappop(self._queue)
        return priority, item

    def peek(self) -> tuple[int, Any]:
        """
        Return but don't remove the highest priority item from the queue.

        For items with equal priority, returns the one that was inserted first.

        :returns:
            A tuple containing (priority, item) with the lowest priority number.
        :raises IndexError:
            If the queue is empty.
        """
        if not self._queue:
            raise IndexError("peek at empty queue")
        priority, _, item = self._queue[0]
        return priority, item

    def get(self) -> tuple[int, Any] | None:
        """
        Remove and return the highest priority item from the queue.

        For items with equal priority, returns the one that was inserted first.
        Unlike pop(), returns None if the queue is empty instead of raising an exception.

        :returns:
            A tuple containing (priority, item), or None if the queue is empty.
        """
        if not self._queue:
            return None
        priority, _, item = heapq.heappop(self._queue)
        return priority, item

View on GitHub (pinned to e318778c9b)

Solutions

  1. Check is_empty() before peeking.
  2. Wrap in try/except IndexError, or use get() which returns None when empty.
  3. Restructure logic to push a sentinel/terminator item instead of peeking on a possibly empty queue.

Example fix

// before
priority, task = queue.peek()
// after
if not queue.is_empty():
    priority, task = queue.peek()
Defensive patterns

Strategy: try-catch

Validate before calling

if queue.is_empty():
    return None

Try / catch

try:
    priority, item = queue.peek()
except IndexError:
    priority, item = None, None

Prevention

When it happens

Trigger: Calling peek() before any push(); peeking after the queue was drained; validation paths in validate_pipeline touching an empty queue.

Common situations: Pre-run inspection code in tests; scheduling loops that peek to decide next steps when no tasks remain; stale assumptions that the queue is non-empty after awaits.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/95d00002f7edb2fe. Report an issue: GitHub.