{"record":{"id":"9d6dc004d5036894","repo":"Textualize/textual","slug":"illegal-select-value-value-r-did-you-mean-to-us","errorCode":null,"errorMessage":"Illegal select value {value!r}. Did you mean to use Select.clear()?","messagePattern":"Illegal select value (.+?)\\. Did you mean to use Select\\.clear\\(\\)\\?","errorType":"exception","errorClass":"InvalidSelectValueError","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_select.py","lineNumber":594,"sourceCode":"\n    def _validate_value(\n        self, value: SelectType | NoSelection\n    ) -> SelectType | NoSelection:\n        \"\"\"Ensure the new value is a valid option.\n\n        If `allow_blank` is `True`, `None` is also a valid value and corresponds to no\n            selection.\n\n        Raises:\n            InvalidSelectValueError: If the new value does not correspond to any known\n                value.\n        \"\"\"\n        if value not in self._legal_values:\n            # It would make sense to use `None` to flag that the Select has no selection,\n            # so we provide a helpful message to catch this mistake in case people didn't\n            # realise we use a special value to flag \"no selection\".\n            help_text = \" Did you mean to use Select.clear()?\" if value is None else \"\"\n            raise InvalidSelectValueError(\n                f\"Illegal select value {value!r}.\" + help_text\n            )\n\n        return value\n\n    def _watch_value(self, value: SelectType | NoSelection) -> None:\n        \"\"\"Update the current value when it changes.\"\"\"\n        self._value = value\n        try:\n            select_current = self.query_one(SelectCurrent)\n        except NoMatches:\n            pass\n        else:\n            if value == self.NULL:\n                select_current.update(self.NULL)\n            else:\n                for index, (prompt, _value) in enumerate(self._options):\n                    if _value == value:","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_select.py#L576-L612","documentation":"Raised by Select._validate_value when assigning a value not in the Select's legal values (the set of values from its options, plus the NULL/blank sentinel if allowed). Assigning None gets an extra hint because Textual uses a special NULL value rather than None for 'no selection'.","triggerScenarios":"select.value = some_value not among the option values; select.value = None on a Select that doesn't allow blank (or ever — None is never legal, Select.NULL is the blank).","commonSituations":"Resetting state by assigning None, passing a raw id/enum from elsewhere that isn't among the options, or setting a value before options are populated.","solutions":["To clear: call select.clear() (requires allow_blank=True) instead of assigning None.","Ensure the value matches exactly (type and identity) one of the option values.","Populate options first, then set value."],"exampleFix":"# before\nselect.value = None\n# after\nselect.clear()  # Select must have been created with allow_blank=True","handlingStrategy":"try-catch","validationCode":"if value in {v for _, v in select._options} or value is select.NULL:\n    select.value = value","typeGuard":null,"tryCatchPattern":"from textual.widgets.select import InvalidSelectValueError\ntry:\n    select.value = value\nexcept InvalidSelectValueError:\n    ...","preventionTips":["Never assign None; use select.clear()","Ensure value matches an option value exactly (type-sensitive)","Populate options before setting value"],"tags":["select","invalid-value","textual","reactive-validator"],"backgroundTag":"invalid-select-value","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}