Textualize/textual · error · OptionDoesNotExist

Unable to remove; there is no option at index {index}

Error message

Unable to remove; there is no option at index {index}

What it means

Raised by OptionList.remove_option_at_index when there is no option at the requested index; the IndexError from self._options[index] is converted to OptionDoesNotExist with a removal-specific message.

Source

Thrown at src/textual/widgets/_option_list.py:629

        option = self.get_option(option_id)
        return self._remove_option(option)

    def remove_option_at_index(self, index: int) -> Self:
        """Remove the option at the given index.

        Args:
            index: The index of the option to remove.

        Returns:
            The `OptionList` instance.

        Raises:
            OptionDoesNotExist: If there is no option with the given index.
        """
        try:
            option = self._options[index]
        except IndexError:
            raise OptionDoesNotExist(
                f"Unable to remove; there is no option at index {index}"
            ) from None
        return self._remove_option(option)

    def _replace_option_prompt(self, index: int, prompt: VisualType) -> None:
        """Replace the prompt of an option in the list.

        Args:
            index: The index of the option to replace the prompt of.
            prompt: The new prompt for the option.

        Raises:
            OptionDoesNotExist: If there is no option with the given index.
        """
        self.get_option_at_index(index)._set_prompt(prompt)
        self._clear_caches()

    def replace_option_prompt(self, option_id: str, prompt: VisualType) -> Self:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Iterate in reverse index order when removing several options, or collect and remove by id.
  2. Bounds-check with option_list.option_count before each removal.
  3. Use remove_option(option_id) inside try/except OptionDoesNotExist for id-based data.

Example fix

# before
for i in to_remove:
    option_list.remove_option_at_index(i)  # indexes shift
# after
for i in sorted(to_remove, reverse=True):
    option_list.remove_option_at_index(i)
Defensive patterns

Strategy: validation

Validate before calling

if 0 <= index < option_list.option_count:
    option_list.remove_option_at_index(index)

Try / catch

from textual.widgets.option_list import OptionDoesNotExist
try:
    option_list.remove_option_at_index(i)
except OptionDoesNotExist:
    pass

Prevention

When it happens

Trigger: Calling remove_option_at_index(i) on an empty list, with i >= option_count, or after prior removals shifted indexes (e.g. looping forward while removing).

Common situations: Removing multiple options in a loop with stale indexes (should remove in reverse order or by id), or removing the highlighted option after the list shrank.

Related errors


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