Textualize/textual · error · IndexError

pop from empty list

Error message

pop from empty list

What it means

An IndexError raised by ListView.pop when the list has zero items (len(self) == 0). pop mirrors list semantics: you cannot remove an item from an empty ListView; the check happens before index normalization, so any pop on an empty list fails regardless of the index argument.

Source

Thrown at src/textual/widgets/_list_view.py:298

            An awaitable that yields control to the event loop
                until the DOM has been updated with the new child item.
        """
        await_mount = self.mount(*items, before=index)
        return await_mount

    def pop(self, index: Optional[int] = None) -> AwaitComplete:
        """Remove last ListItem from ListView or
           Remove ListItem from ListView by index

        Args:
            index: index of ListItem to remove from ListView

        Returns:
            An awaitable that yields control to the event loop until
                the DOM has been updated to reflect item being removed.
        """
        if len(self) == 0:
            raise IndexError("pop from empty list")

        index = index if index is not None else -1
        item_to_remove = self.query("ListItem")[index]
        normalized_index = index if index >= 0 else index + len(self)

        async def do_pop() -> None:
            """Remove the item and update the highlighted index."""
            await item_to_remove.remove()
            if self.index is not None:
                if normalized_index < self.index:
                    self.index -= 1
                elif normalized_index == self.index:
                    old_index = self.index
                    # Force a re-validation of the index
                    self.index = self.index
                    # If the index hasn't changed, the watcher won't be called
                    # but we need to update the highlighted item
                    if old_index == self.index:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Guard the call: if len(list_view): list_view.pop().
  2. Disable or no-op the remove action when list_view.is_empty / len == 0.
  3. Catch IndexError defensively around batch removal loops.

Example fix

# before
item = list_view.pop()

# after
item = list_view.pop() if len(list_view) else None
Defensive patterns

Strategy: validation

Validate before calling

item = list_view.pop() if len(list_view) else None

Try / catch

try:
    item = list_view.pop()
except IndexError:
    item = None

Prevention

When it happens

Trigger: Calling list_view.pop() (or pop(i)) after all ListItems were removed or before any were added; a remove-item keybinding handler firing when the list is empty.

Common situations: Delete-key handlers bound to ListView that don't check emptiness; popping in a loop driven by external state that empties the list mid-iteration; UI where items are removed asynchronously.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/63054d3e07233e20. Report an issue: GitHub.