iOfficeAI/OfficeCLI · error · ArgumentException

Column {startCol} out of range (max: XFD)

Error message

Column {startCol} out of range (max: XFD)

What it means

ArgumentException thrown in ReadSourceData when the start column of the source range exceeds Excel's hard maximum (XFD = column 16384). This R6-3 guard rejects oversized column letters (e.g. XFE, XFZ, ZZZZ) that previously parsed into huge indices, producing a giant colCount and crashing the renderer or writing an invalid source range into the cache.

Source

Thrown at src/officecli/Core/PivotTableHelper.Cache.cs:277

        var sheetData = ws.GetFirstChild<SheetData>();
        if (sheetData == null) return (Array.Empty<string>(), new List<string[]>(), Array.Empty<uint?>());

        // Parse range "A1:D100"
        var parts = sourceRef.Replace("$", "").Split(':');
        if (parts.Length != 2) throw new ArgumentException($"Invalid source range: {sourceRef}");

        var (startCol, startRow) = ParseCellRef(parts[0]);
        var (endCol, endRow) = ParseCellRef(parts[1]);

        var startColIdx = ColToIndex(startCol);
        var endColIdx = ColToIndex(endCol);
        // R6-3: reject columns beyond Excel's hard max (XFD = 16384). Previously
        // XFE / XFZ / ZZZZ silently parsed into oversized indices, produced a
        // giant colCount, and either crashed deep in the renderer or wrote an
        // invalid source range into the cache.
        const int ExcelMaxColumn = 16384; // XFD
        if (startColIdx > ExcelMaxColumn)
            throw new ArgumentException($"Column {startCol} out of range (max: XFD)");
        if (endColIdx > ExcelMaxColumn)
            throw new ArgumentException($"Column {endCol} out of range (max: XFD)");
        var colCount = endColIdx - startColIdx + 1;

        // Read all rows in range. We also capture the StyleIndex of the first
        // non-empty data cell per column (skipping the header row) so pivot
        // value cells can inherit the source column's number format. This
        // mirrors how Excel's pivot engine picks the column format: it looks
        // at the data-area formatting, not the header.
        var rows = new List<string[]>();
        var columnStyleIds = new uint?[colCount];
        var sst = sourceSheet.OpenXmlPackage is SpreadsheetDocument doc
            ? doc.WorkbookPart?.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()
            : null;

        foreach (var row in sheetData.Elements<Row>())
        {
            var rowIdx = (int)(row.RowIndex?.Value ?? 0);

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Keep the start column within A..XFD (1..16384), e.g. sourceRef="A1:D100".
  2. If you generated the column letter programmatically, clamp/validate it against the 16384 maximum before building the range.
  3. Double-check you did not swap row and column in the corner cell.

Example fix

// before
sourceRef="XFE1:Z100"
// after
sourceRef="A1:Z100"
Defensive patterns

Strategy: validation

Validate before calling

// Reject start columns beyond XFD (16384):
static int ColToIndex(string col)
{
    int idx = 0;
    foreach (var ch in col.ToUpperInvariant()) { if (ch < 'A' || ch > 'Z') return -1; idx = idx * 26 + (ch - 'A' + 1); }
    return idx;
}
static bool StartColumnInRange(string sourceRef)
    => ColToIndex(sourceRef.Replace("$","").Split(':')[0].TrimStart("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray())) <= 16384;

Prevention

When it happens

Trigger: Passing a sourceRef whose first corner uses a column beyond XFD — e.g. 'XFE1:ZZZ100', 'XFZ1:A1', or a mistyped multi-letter column like 'ZZZZ1'. ColToIndex returns >16384 and the guard fires.

Common situations: Typing a long column-letter string by hand; programmatically generating column letters past XFD; mistaking a row number for a column; copied ranges from a tool that does not enforce Excel's 16384-column limit.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/76f17f3c13e3844e. Report an issue: GitHub.