spectreconsole/spectre.console · error · IndexOutOfRangeException

Table row index cannot be negative.

Error message

Table row index cannot be negative.

What it means

TableRowCollection.Update(int row, int column, IRenderable cellData) validates the row index first. If row < 0 it throws IndexOutOfRangeException with 'Table row index cannot be negative.' The method is the in-place cell replacement API used by table.UpdateCell-style extensions.

Source

Thrown at src/Spectre.Console/Widgets/Table/TableRowCollection.cs:94

            return _list.IndexOf(row);
        }
    }

    /// <summary>
    /// Update a table cell at the specified index.
    /// </summary>
    /// <param name="row">Index of cell row.</param>
    /// <param name="column">index of cell column.</param>
    /// <param name="cellData">The new cells details.</param>
    public void Update(int row, int column, IRenderable cellData)
    {
        ArgumentNullException.ThrowIfNull(cellData);

        lock (_lock)
        {
            if (row < 0)
            {
                throw new IndexOutOfRangeException("Table row index cannot be negative.");
            }
            else if (row >= _list.Count)
            {
                throw new IndexOutOfRangeException("Table row index cannot exceed the number of rows in the table.");
            }

            var tableRow = _list.ElementAt(row);
            var currentRenderables = tableRow.ToList();

            if (column < 0)
            {
                throw new IndexOutOfRangeException("Table column index cannot be negative.");
            }
            else if (column >= currentRenderables.Count)
            {
                throw new IndexOutOfRangeException("Table column index cannot exceed the number of rows in the table.");
            }

View on GitHub (pinned to 0acc92fada)

Solutions

  1. Validate row >= 0 before calling Update.
  2. Bound-check against table.Rows.Count and clamp/skip when out of range.
  3. Recompute indices after structural changes (Insert/RemoveAt) that shift row positions.

Example fix

// before
table.Rows.Update(rowIndex, colIndex, cell);

// after
if (rowIndex >= 0 && rowIndex < table.Rows.Count)
    table.Rows.Update(rowIndex, colIndex, cell);
Defensive patterns

Strategy: validation

Validate before calling

if (row < 0) throw new ArgumentOutOfRangeException(nameof(row));
table.Rows.Update(row, column, cell);

Prevention

When it happens

Trigger: Calling Update with a negative row argument, e.g. a computed index that underflows, or passing a position from data/calculations that went below zero.

Common situations: Off-by-one when subtracting from a count; using an index variable decremented in a loop past zero; passing an unchecked external index; off-by-one after a RemoveAt shifts indices.

Related errors


AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13). Data as JSON: /api/errors/56a144faa5364c1a. Report an issue: GitHub.