Textualize/textual · error · ColumnDoesNotExist

Column index {column_index!r} is not valid.

Error message

Column index {column_index!r} is not valid.

What it means

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.

Source

Thrown at src/textual/widgets/_data_table.py:1079

        data = self._data
        for row_metadata in self.ordered_rows:
            row_key = row_metadata.key
            yield data[row_key][column_key]

    def get_column_at(self, column_index: int) -> Iterable[CellType]:
        """Get the values from the column at a given index.

        Args:
            column_index: The index of the column.

        Returns:
            A generator which yields the cells in the column.

        Raises:
            ColumnDoesNotExist: If there is no column with the given index.
        """
        if not self.is_valid_column_index(column_index):
            raise ColumnDoesNotExist(f"Column index {column_index!r} is not valid.")

        column_key = self._column_locations.get_key(column_index)
        yield from self.get_column(column_key)

    def get_column_index(self, column_key: ColumnKey | str) -> int:
        """Return the current index for the column identified by column_key.

        Args:
            column_key: The column key to find the current index of.

        Returns:
            The current index of the specified column key.

        Raises:
            ColumnDoesNotExist: If the column key does not exist.
        """
        if column_key not in self._column_locations:
            raise ColumnDoesNotExist(f"No column exists for column_key={column_key!r}")

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Bounds-check first: table.is_valid_column_index(index).
  2. Prefer key-based get_column with keys from add_column when the schema can change.
  3. Recompute len(table.columns) right before access after mutations.
  4. Catch ColumnDoesNotExist defensively.

Example fix

# before
col = list(table.get_column_at(3))

# after
if table.is_valid_column_index(3):
    col = list(table.get_column_at(3))
else:
    col = []
Defensive patterns

Strategy: validation

Validate before calling

col = list(table.get_column_at(i)) if table.is_valid_column_index(i) else []

Try / catch

from textual.widgets._data_table import ColumnDoesNotExist
try:
    col = list(table.get_column_at(i))
except ColumnDoesNotExist:
    col = []

Prevention

When it happens

Trigger: Calling get_column_at with index >= len(table.columns) or < -len(table.columns); using an index captured before remove_column or column reordering.

Common situations: 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)).

Related errors


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