{"record":{"id":"b987e07862f2f5e7","repo":"Textualize/textual","slug":"column-index-column-index-r-is-not-valid","errorCode":null,"errorMessage":"Column index {column_index!r} is not valid.","messagePattern":"Column index (.+?) is not valid\\.","errorType":"exception","errorClass":"ColumnDoesNotExist","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_data_table.py","lineNumber":1079,"sourceCode":"        data = self._data\n        for row_metadata in self.ordered_rows:\n            row_key = row_metadata.key\n            yield data[row_key][column_key]\n\n    def get_column_at(self, column_index: int) -> Iterable[CellType]:\n        \"\"\"Get the values from the column at a given index.\n\n        Args:\n            column_index: The index of the column.\n\n        Returns:\n            A generator which yields the cells in the column.\n\n        Raises:\n            ColumnDoesNotExist: If there is no column with the given index.\n        \"\"\"\n        if not self.is_valid_column_index(column_index):\n            raise ColumnDoesNotExist(f\"Column index {column_index!r} is not valid.\")\n\n        column_key = self._column_locations.get_key(column_index)\n        yield from self.get_column(column_key)\n\n    def get_column_index(self, column_key: ColumnKey | str) -> int:\n        \"\"\"Return the current index for the column identified by column_key.\n\n        Args:\n            column_key: The column key to find the current index of.\n\n        Returns:\n            The current index of the specified column key.\n\n        Raises:\n            ColumnDoesNotExist: If the column key does not exist.\n        \"\"\"\n        if column_key not in self._column_locations:\n            raise ColumnDoesNotExist(f\"No column exists for column_key={column_key!r}\")","sourceCodeStart":1061,"sourceCodeEnd":1097,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_data_table.py#L1061-L1097","documentation":"Raised by DataTable.get_column_at when the integer column_index fails is_valid_column_index (out of range for the current number of columns). Column indices shift when columns are inserted, removed, or reordered, so a previously valid index can become invalid.","triggerScenarios":"Calling get_column_at with index >= len(table.columns) or < -len(table.columns); using an index captured before remove_column or column reordering.","commonSituations":"Hardcoding column positions in a table built from dynamic data; iterating columns after a schema change; off-by-one when looping over range(len(table.columns)).","solutions":["Bounds-check first: table.is_valid_column_index(index).","Prefer key-based get_column with keys from add_column when the schema can change.","Recompute len(table.columns) right before access after mutations.","Catch ColumnDoesNotExist defensively."],"exampleFix":"# before\ncol = list(table.get_column_at(3))\n\n# after\nif table.is_valid_column_index(3):\n    col = list(table.get_column_at(3))\nelse:\n    col = []","handlingStrategy":"validation","validationCode":"col = list(table.get_column_at(i)) if table.is_valid_column_index(i) else []","typeGuard":null,"tryCatchPattern":"from textual.widgets._data_table import ColumnDoesNotExist\ntry:\n    col = list(table.get_column_at(i))\nexcept ColumnDoesNotExist:\n    col = []","preventionTips":["Avoid hardcoding column positions for dynamic tables","Use key-based access when columns can be reordered/removed","Recompute len(table.columns) after mutations"],"tags":["data-table","index-out-of-range","textual","column"],"backgroundTag":"index-out-of-range","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}