{"record":{"id":"95d00002f7edb2fe","repo":"deepset-ai/haystack","slug":"peek-at-empty-queue","errorCode":null,"errorMessage":"peek at empty queue","messagePattern":"peek at empty queue","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"haystack/core/pipeline/utils.py","lineNumber":140,"sourceCode":"        \"\"\"\n        if not self._queue:\n            raise IndexError(\"pop from empty queue\")\n        priority, _, item = heapq.heappop(self._queue)\n        return priority, item\n\n    def peek(self) -> tuple[int, Any]:\n        \"\"\"\n        Return but don't remove the highest priority item from the queue.\n\n        For items with equal priority, returns the one that was inserted first.\n\n        :returns:\n            A tuple containing (priority, item) with the lowest priority number.\n        :raises IndexError:\n            If the queue is empty.\n        \"\"\"\n        if not self._queue:\n            raise IndexError(\"peek at empty queue\")\n        priority, _, item = self._queue[0]\n        return priority, item\n\n    def get(self) -> tuple[int, Any] | None:\n        \"\"\"\n        Remove and return the highest priority item from the queue.\n\n        For items with equal priority, returns the one that was inserted first.\n        Unlike pop(), returns None if the queue is empty instead of raising an exception.\n\n        :returns:\n            A tuple containing (priority, item), or None if the queue is empty.\n        \"\"\"\n        if not self._queue:\n            return None\n        priority, _, item = heapq.heappop(self._queue)\n        return priority, item\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/core/pipeline/utils.py#L122-L158","documentation":"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.","triggerScenarios":"Calling peek() before any push(); peeking after the queue was drained; validation paths in validate_pipeline touching an empty queue.","commonSituations":"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.","solutions":["Check is_empty() before peeking.","Wrap in try/except IndexError, or use get() which returns None when empty.","Restructure logic to push a sentinel/terminator item instead of peeking on a possibly empty queue."],"exampleFix":"// before\npriority, task = queue.peek()\n// after\nif not queue.is_empty():\n    priority, task = queue.peek()\n","handlingStrategy":"try-catch","validationCode":"if queue.is_empty():\n    return None","typeGuard":null,"tryCatchPattern":"try:\n    priority, item = queue.peek()\nexcept IndexError:\n    priority, item = None, None","preventionTips":["Guard peek with is_empty() in scheduling/validation loops.","Use get() (returns None when empty) where a non-raising read suffices.","Re-check emptiness after any await in concurrent code."],"tags":["queue","indexerror","internal-api"],"backgroundTag":"peek-at-empty-queue","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}