{"record":{"id":"1a1cbc5ec767ad95","repo":"spectreconsole/spectre.console","slug":"column-spanning-is-not-supported-in-table-header-r","errorCode":null,"errorMessage":"Column spanning is not supported in table header rows.","messagePattern":"Column spanning is not supported in table header rows\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Spectre.Console/Widgets/Table/TableColumn.cs","lineNumber":21,"sourceCode":"/// <summary>\n/// Represents a table column.\n/// </summary>\npublic sealed class TableColumn : IColumn\n{\n    private IRenderable _header = null!;\n    private IRenderable? _footer;\n\n    /// <summary>\n    /// Gets or sets the column header.\n    /// </summary>\n    public IRenderable Header\n    {\n        get => _header;\n        set\n        {\n            if (value is TableCell cell && cell.ColumnSpan > 1)\n            {\n                throw new InvalidOperationException(\"Column spanning is not supported in table header rows.\");\n            }\n\n            _header = value ?? throw new ArgumentNullException(nameof(value));\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the column footer.\n    /// </summary>\n    public IRenderable? Footer\n    {\n        get => _footer;\n        set\n        {\n            if (value is TableCell cell && cell.ColumnSpan > 1)\n            {\n                throw new InvalidOperationException(\"Column spanning is not supported in table footer rows.\");\n            }","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/spectreconsole/spectre.console/blob/0acc92fada6c42f13984e79c2b5f3d993bdfb099/src/Spectre.Console/Widgets/Table/TableColumn.cs#L3-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ncolumn.Header = new TableCell(\"Merged\").Span(2);\n\n// after\ncolumn.Header = new Markup(\"Header text\");","handlingStrategy":"validation","validationCode":"var headerCell = value as TableCell;\nif (headerCell is not null && headerCell.ColumnSpan > 1)\n    throw new InvalidOperationException(\"Headers cannot span columns.\");\ncolumn.Header = value;","typeGuard":"static bool IsSafeHeader(IRenderable r) => r is not TableCell tc || tc.ColumnSpan <= 1;","tryCatchPattern":null,"preventionTips":["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."],"tags":["table","header","column-span","invalid-operation"],"backgroundTag":null,"analyzedSha":"0acc92fada6c42f13984e79c2b5f3d993bdfb099","analyzedAt":"2026-08-13T18:27:21.983Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}