{"record":{"id":"76f17f3c13e3844e","repo":"iOfficeAI/OfficeCLI","slug":"column-startcol-out-of-range-max-xfd","errorCode":null,"errorMessage":"Column {startCol} out of range (max: XFD)","messagePattern":"Column (.+?) out of range \\(max: XFD\\)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Cache.cs","lineNumber":277,"sourceCode":"        var sheetData = ws.GetFirstChild<SheetData>();\n        if (sheetData == null) return (Array.Empty<string>(), new List<string[]>(), Array.Empty<uint?>());\n\n        // Parse range \"A1:D100\"\n        var parts = sourceRef.Replace(\"$\", \"\").Split(':');\n        if (parts.Length != 2) throw new ArgumentException($\"Invalid source range: {sourceRef}\");\n\n        var (startCol, startRow) = ParseCellRef(parts[0]);\n        var (endCol, endRow) = ParseCellRef(parts[1]);\n\n        var startColIdx = ColToIndex(startCol);\n        var endColIdx = ColToIndex(endCol);\n        // R6-3: reject columns beyond Excel's hard max (XFD = 16384). Previously\n        // XFE / XFZ / ZZZZ silently parsed into oversized indices, produced a\n        // giant colCount, and either crashed deep in the renderer or wrote an\n        // invalid source range into the cache.\n        const int ExcelMaxColumn = 16384; // XFD\n        if (startColIdx > ExcelMaxColumn)\n            throw new ArgumentException($\"Column {startCol} out of range (max: XFD)\");\n        if (endColIdx > ExcelMaxColumn)\n            throw new ArgumentException($\"Column {endCol} out of range (max: XFD)\");\n        var colCount = endColIdx - startColIdx + 1;\n\n        // Read all rows in range. We also capture the StyleIndex of the first\n        // non-empty data cell per column (skipping the header row) so pivot\n        // value cells can inherit the source column's number format. This\n        // mirrors how Excel's pivot engine picks the column format: it looks\n        // at the data-area formatting, not the header.\n        var rows = new List<string[]>();\n        var columnStyleIds = new uint?[colCount];\n        var sst = sourceSheet.OpenXmlPackage is SpreadsheetDocument doc\n            ? doc.WorkbookPart?.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()\n            : null;\n\n        foreach (var row in sheetData.Elements<Row>())\n        {\n            var rowIdx = (int)(row.RowIndex?.Value ?? 0);","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Cache.cs#L259-L295","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Keep the start column within A..XFD (1..16384), e.g. sourceRef=\"A1:D100\".","If you generated the column letter programmatically, clamp/validate it against the 16384 maximum before building the range.","Double-check you did not swap row and column in the corner cell."],"exampleFix":"// before\nsourceRef=\"XFE1:Z100\"\n// after\nsourceRef=\"A1:Z100\"","handlingStrategy":"validation","validationCode":"// Reject start columns beyond XFD (16384):\nstatic int ColToIndex(string col)\n{\n    int idx = 0;\n    foreach (var ch in col.ToUpperInvariant()) { if (ch < 'A' || ch > 'Z') return -1; idx = idx * 26 + (ch - 'A' + 1); }\n    return idx;\n}\nstatic bool StartColumnInRange(string sourceRef)\n    => ColToIndex(sourceRef.Replace(\"$\",\"\").Split(':')[0].TrimStart(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\".ToCharArray())) <= 16384;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep start columns within A..XFD (1..16384).","Validate generated column letters against the 16384 max.","Do not swap row and column in the corner cell."],"tags":["pivot-table","excel","input-validation","range","column-limit","ooxml","officecli"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}