{"record":{"id":"2b41c609fb6443e1","repo":"Textualize/textual","slug":"unable-to-remove-there-is-no-option-at-index-ind","errorCode":null,"errorMessage":"Unable to remove; there is no option at index {index}","messagePattern":"Unable to remove; there is no option at index (.+?)","errorType":"exception","errorClass":"OptionDoesNotExist","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_option_list.py","lineNumber":629,"sourceCode":"        option = self.get_option(option_id)\n        return self._remove_option(option)\n\n    def remove_option_at_index(self, index: int) -> Self:\n        \"\"\"Remove the option at the given index.\n\n        Args:\n            index: The index of the option to remove.\n\n        Returns:\n            The `OptionList` instance.\n\n        Raises:\n            OptionDoesNotExist: If there is no option with the given index.\n        \"\"\"\n        try:\n            option = self._options[index]\n        except IndexError:\n            raise OptionDoesNotExist(\n                f\"Unable to remove; there is no option at index {index}\"\n            ) from None\n        return self._remove_option(option)\n\n    def _replace_option_prompt(self, index: int, prompt: VisualType) -> None:\n        \"\"\"Replace the prompt of an option in the list.\n\n        Args:\n            index: The index of the option to replace the prompt of.\n            prompt: The new prompt for the option.\n\n        Raises:\n            OptionDoesNotExist: If there is no option with the given index.\n        \"\"\"\n        self.get_option_at_index(index)._set_prompt(prompt)\n        self._clear_caches()\n\n    def replace_option_prompt(self, option_id: str, prompt: VisualType) -> Self:","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_option_list.py#L611-L647","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Iterate in reverse index order when removing several options, or collect and remove by id.","Bounds-check with option_list.option_count before each removal.","Use remove_option(option_id) inside try/except OptionDoesNotExist for id-based data."],"exampleFix":"# before\nfor i in to_remove:\n    option_list.remove_option_at_index(i)  # indexes shift\n# after\nfor i in sorted(to_remove, reverse=True):\n    option_list.remove_option_at_index(i)","handlingStrategy":"validation","validationCode":"if 0 <= index < option_list.option_count:\n    option_list.remove_option_at_index(index)","typeGuard":null,"tryCatchPattern":"from textual.widgets.option_list import OptionDoesNotExist\ntry:\n    option_list.remove_option_at_index(i)\nexcept OptionDoesNotExist:\n    pass","preventionTips":["Remove in reverse index order in loops","Prefer remove_option(id) with existence checks","Handle removal of the hovered/highlighted option explicitly"],"tags":["optionlist","remove","index-out-of-range","textual"],"backgroundTag":"index-out-of-bounds","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}