{"record":{"id":"d36d40aa1500eb7d","repo":"Textualize/textual","slug":"expected-2-or-3-values-got-len-selection","errorCode":null,"errorMessage":"Expected 2 or 3 values, got {len(selection)}","messagePattern":"Expected 2 or 3 values, got (.+?)","errorType":"exception","errorClass":"SelectionError","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_selection_list.py","lineNumber":472,"sourceCode":"        Args:\n            selection: The selection data.\n\n        Returns:\n            An instance of a `Selection`.\n\n        Raises:\n            SelectionError: If the selection was badly-formed.\n        \"\"\"\n\n        # If we've been given a tuple of some sort, turn that into a proper\n        # Selection.\n        if isinstance(selection, tuple):\n            if len(selection) == 2:\n                selection = cast(\n                    \"tuple[ContentText, SelectionType, bool]\", (*selection, False)\n                )\n            elif len(selection) != 3:\n                raise SelectionError(f\"Expected 2 or 3 values, got {len(selection)}\")\n            selection = Selection[SelectionType](*selection)\n\n        # At this point we should have a proper selection.\n        assert isinstance(selection, Selection)\n\n        # If the initial state for this is that it's selected, add it to the\n        # selected collection.\n        if selection.initial_state:\n            self._select(selection.value)\n\n        return selection\n\n    def _toggle_highlighted_selection(self) -> None:\n        \"\"\"Toggle the state of the highlighted selection.\n\n        If nothing is selected in the list this is a non-operation.\n        \"\"\"\n        if self.highlighted is not None:","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_selection_list.py#L454-L490","documentation":"Raised by SelectionList._make_selection when a tuple passed as an option has neither 2 elements (prompt, value) nor 3 elements (prompt, value, initial_state). Tuples of any other length cannot be interpreted as a Selection.","triggerScenarios":"SelectionList([(\"a\", 1, True, \"extra\")]) or SelectionList([(\"only-prompt\",)]), or add_options with malformed tuples.","commonSituations":"Building selection tuples dynamically and appending extra metadata, unpacking rows from a database with extra columns, or forgetting the initial-state boolean.","solutions":["Use exactly (prompt, value) or (prompt, value, initial_state: bool).","Use Selection(prompt, value, initial_state) objects explicitly for clarity.","Slice extra fields out of data rows before passing."],"exampleFix":"# before\nSelectionList([(row[0], row[1], row[2], row[3]) for row in rows])\n# after\nSelectionList([(row[0], row[1], bool(row[2])) for row in rows])","handlingStrategy":"type-guard","validationCode":"items = [tuple(t[:3]) if len(t) > 3 else t for t in items]  # or validate len(t) in (2,3)","typeGuard":"def is_valid_selection_tuple(t) -> bool: return isinstance(t, tuple) and len(t) in (2, 3)","tryCatchPattern":null,"preventionTips":["Construct Selection objects instead of raw tuples","Slice DB rows to exactly the fields you need"],"tags":["selection-list","tuple-length","textual","validation"],"backgroundTag":"invalid-tuple-shape","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}