spectreconsole/spectre.console · error · InvalidOperationException

The number of row columns (including spans) are greater than

Error message

The number of row columns (including spans) are greater than the number of table columns. Expected {_table.Columns.Count} but got {totalSpan}.

What it means

When adding a row (AddRow overloads), CreateRow sums each cell's contribution: a plain IRenderable counts as 1, a TableCell counts as its ColumnSpan. If the total exceeds the number of columns defined on the table, it throws InvalidOperationException. Note the asymmetric behavior: fewer cells than columns is allowed (the method pads with empty Text cells), but more is rejected. The message wording ('are greater than') is slightly ungrammatical.

Source

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

        // Calculate total span considering TableCell instances
        var totalSpan = 0;
        for (var i = 0; i < row.Count; i++)
        {
            var cell = row[i];
            if (cell is TableCell tableCell)
            {
                totalSpan += tableCell.ColumnSpan;
            }
            else
            {
                totalSpan++;
            }
        }

        if (totalSpan > _table.Columns.Count)
        {
            throw new InvalidOperationException($"The number of row columns (including spans) are greater than the number of table columns. Expected {_table.Columns.Count} but got {totalSpan}.");
        }

        // Need to add missing columns
        if (totalSpan < _table.Columns.Count)
        {
            var diff = _table.Columns.Count - totalSpan;
            Enumerable.Range(0, diff).ForEach(_ => row.Add(Text.Empty));
        }

        return row;
    }
}

View on GitHub (pinned to 0acc92fada)

Solutions

  1. Ensure table columns count >= total row span before adding rows: add missing AddColumn calls first.
  2. Reduce the cells in the row, or lower a TableCell span, so the sum <= table.Columns.Count.
  3. If rows may have fewer cells, rely on the built-in padding (do nothing) — only excess throws.
  4. Compute span as min(requestedSpan, table.Columns.Count - otherCells).

Example fix

// before
var table = new Table();
table.AddColumns("A", "B", "C");
table.AddRow(new TableCell("wide").Span(3), new Markup("extra")); // total 4 > 3

// after
var table = new Table();
table.AddColumns("A", "B", "C", "D");
table.AddRow(new TableCell("wide").Span(3), new Markup("extra")); // total 4 == 4
Defensive patterns

Strategy: validation

Validate before calling

int totalSpan = rowCells.Sum(c => c is TableCell tc ? tc.ColumnSpan : 1);
if (totalSpan > table.Columns.Count)
    table.AddColumns(Enumerable.Range(0, totalSpan - table.Columns.Count).Select(_ => string.Empty).ToArray());
table.AddRow(rowCells);

Prevention

When it happens

Trigger: Defining N columns via AddColumn/AddColumns but adding a row whose cells/spans sum to > N — e.g. 3 columns but a row with 4 cells, or a TableCell.Span(3) plus two more plain cells (total 4) against 3 columns.

Common situations: Forgetting to AddColumn(s) before AddRow; mismatched counts after dynamically adding/removing columns; a spanning cell computed from data whose span pushes the total over; building rows from a 2D array whose width exceeds the declared columns.

Related errors


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