spectreconsole/spectre.console · error · InvalidOperationException
Column spanning is not supported in table header rows.
Error message
Column spanning is not supported in table header rows.
What it means
The TableColumn.Header setter stores the per-column header renderable. Spectre.Console supports column spanning only in body rows, not in the header row; assigning a TableCell whose ColumnSpan > 1 to Header throws InvalidOperationException. This is enforced because header layout has no merging logic.
Source
Thrown at src/Spectre.Console/Widgets/Table/TableColumn.cs:21
/// <summary>
/// Represents a table column.
/// </summary>
public sealed class TableColumn : IColumn
{
private IRenderable _header = null!;
private IRenderable? _footer;
/// <summary>
/// Gets or sets the column header.
/// </summary>
public IRenderable Header
{
get => _header;
set
{
if (value is TableCell cell && cell.ColumnSpan > 1)
{
throw new InvalidOperationException("Column spanning is not supported in table header rows.");
}
_header = value ?? throw new ArgumentNullException(nameof(value));
}
}
/// <summary>
/// Gets or sets the column footer.
/// </summary>
public IRenderable? Footer
{
get => _footer;
set
{
if (value is TableCell cell && cell.ColumnSpan > 1)
{
throw new InvalidOperationException("Column spanning is not supported in table footer rows.");
}View on GitHub (pinned to 0acc92fada)
Solutions
- Use a plain renderable (new Markup(text)) for headers instead of a spanning TableCell.
- If you hold a TableCell, reset or avoid its span before assigning to Header, or create a fresh non-spanning cell.
- Build header content via the string overload new TableColumn("Header text") which wraps a Markup, never a spanned TableCell.
Example fix
// before
column.Header = new TableCell("Merged").Span(2);
// after
column.Header = new Markup("Header text"); Defensive patterns
Strategy: validation
Validate before calling
var headerCell = value as TableCell;
if (headerCell is not null && headerCell.ColumnSpan > 1)
throw new InvalidOperationException("Headers cannot span columns.");
column.Header = value; Type guard
static bool IsSafeHeader(IRenderable r) => r is not TableCell tc || tc.ColumnSpan <= 1;
Prevention
- Never assign a TableCell that has a span to a header; use plain Markup.
- Keep header and body cell construction in separate factories.
- Audit any code path that reuses body cells as headers.
When it happens
Trigger: Setting column.Header = new TableCell(markup).Span(2); constructing new TableColumn(someSpanningTableCell); or reusing a body TableCell (which was given a span) as a header renderable.
Common situations: Reusing a TableCell object across header and body by mistake; attempting to visually merge header columns (unsupported feature); building headers from the same factory that produces spanning body cells; assuming span is a global cell property rather than body-only.
Related errors
- Column spanning is not supported in table {rowType} rows.
- Column spanning is not supported in table footer rows.
- The number of row columns (including spans) are greater than
- Cannot add new columns to table with existing rows.
- Column span must be at least 1.
AI-assisted analysis of spectreconsole/spectre.console@0acc92fada (2026-08-13).
Data as JSON: /api/errors/1a1cbc5ec767ad95.
Report an issue: GitHub.