iOfficeAI/OfficeCLI · error · ArgumentException

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

Error message

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

What it means

ArgumentException thrown in ReadSourceData when the END column of the source range exceeds Excel's hard maximum (XFD = column 16384). Same R6-3 guard as the start-column check, applied to the second corner of the range.

Source

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

        // 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);
            if (rowIdx < startRow || rowIdx > endRow) continue;

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Keep the end column within A..XFD (1..16384), e.g. sourceRef="A1:XFD100" at most.
  2. Clamp generated end-column letters to the 16384 maximum.
  3. Verify the end corner is not past the real data extent / sheet limit.

Example fix

// before
sourceRef="A1:XFE100"
// after
sourceRef="A1:XFD100"
Defensive patterns

Strategy: validation

Validate before calling

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 EndColumnInRange(string sourceRef)
{
    var endCell = sourceRef.Replace("$","").Split(':')[1];
    var letters = new string(endCell.TakeWhile(char.IsLetter).ToArray());
    return ColToIndex(letters) <= 16384;
}

Prevention

When it happens

Trigger: Passing a sourceRef whose second corner uses a column beyond XFD — e.g. 'A1:XFE100', 'A1:XFZ100', or 'A1:ZZZZ'. The end column's ColToIndex exceeds 16384 and the guard fires.

Common situations: Hand-typing an oversized end column; programmatic column-letter generation past XFD; a range that 'extends past the sheet'; mistyping the end corner.

Related errors


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