{"record":{"id":"b4d51c45ab3c291e","repo":"iOfficeAI/OfficeCLI","slug":"pivot-at-ptposition-does-not-fit-computed-end-c","errorCode":null,"errorMessage":"pivot at {ptPosition} does not fit: computed end col={minEndColIdx} row={minEndRow} exceeds sheet dimensions (max XFD1048576)","messagePattern":"pivot at (.+?) does not fit: computed end col=(.+?) row=(.+?) exceeds sheet dimensions \\(max XFD1048576\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs","lineNumber":1754,"sourceCode":"            const int ExcelMaxCol = 16384; // XFD\n            const int ExcelMaxRow = 1048576;\n            var srcRefParts = sourceRef.Replace(\"$\", \"\").Split(':');\n            if (srcRefParts.Length == 2)\n            {\n                var (srcStartCol, srcStartRow) = ParseCellReference(srcRefParts[0].Trim().ToUpperInvariant());\n                var (srcEndCol, srcEndRow)     = ParseCellReference(srcRefParts[1].Trim().ToUpperInvariant());\n                int nSourceCols = ColumnNameToIndex(srcEndCol) - ColumnNameToIndex(srcStartCol) + 1;\n                int nDataRows   = srcEndRow - srcStartRow; // header excluded\n                var (anchorColStr, anchorRow) = ParseCellReference(ptPosition.ToUpperInvariant());\n                int anchorColIdx = ColumnNameToIndex(anchorColStr);\n                // Conservative lower-bound: pivot needs at least nSourceCols columns\n                // (row-label cols + value cols + grand-total col) and at least\n                // nDataRows + 2 rows (header + data rows + grand-total row).\n                int minEndColIdx = anchorColIdx + nSourceCols - 1;\n                int minEndRow    = anchorRow + nDataRows + 1;\n                if (minEndColIdx > ExcelMaxCol || minEndRow > ExcelMaxRow)\n                {\n                    throw new ArgumentException(\n                        $\"pivot at {ptPosition} does not fit: computed end col={minEndColIdx} row={minEndRow} exceeds sheet dimensions (max XFD1048576)\");\n                }\n\n                // CONSISTENCY(pivot-output-overlap): two pivot tables whose\n                // <x:location> rectangles overlap on the same sheet make\n                // Excel surface a \"found a problem\" repair dialog because\n                // the output cells fight for ownership. Mirror the T4\n                // table-table overlap check using the conservative output\n                // bounds computed above. Cross-sheet pivots are fine.\n                var newPivotRange = $\"{IndexToColumnName(anchorColIdx)}{anchorRow}:\" +\n                                    $\"{IndexToColumnName(minEndColIdx)}{minEndRow}\";\n                foreach (var existingPivot in ptWorksheet.PivotTableParts\n                    .Select(ptp => ptp.PivotTableDefinition)\n                    .Where(d => d != null))\n                {\n                    var existingLoc = existingPivot!.Location?.Reference?.Value;\n                    if (string.IsNullOrEmpty(existingLoc)) continue;\n                    if (RangesOverlap(newPivotRange.ToUpperInvariant(), existingLoc.ToUpperInvariant()))","sourceCodeStart":1736,"sourceCodeEnd":1772,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Tables.cs#L1736-L1772","documentation":"Thrown by AddPivotTable's fit check when the conservative lower-bound output rectangle would extend beyond Excel's sheet maximums. The handler computes the minimum end column as anchorCol + nSourceCols - 1 and minimum end row as anchorRow + nDataRows + 1 (header + data + grand-total); if either exceeds ExcelMaxCol (16384/XFD) or ExcelMaxRow (1048576) it rejects rather than writing a pivot Excel cannot place.","triggerScenarios":"Calling Add('/Report/pivottable', ...) with a large source range and an anchor position near the right or bottom edge, e.g. position=XFB1 with a 20-column source, or a position whose computed end exceeds XFD1048576.","commonSituations":"Auto-positioning collides with the edge, supplying a position far down/right, or a source with many columns/rows.","solutions":["Move the anchor left/up, e.g. position=A1 or a column well inside the sheet.","Omit position to let the handler auto-place after the source range (it picks a column 2 right of the source end).","Reduce the source range size if the pivot genuinely cannot fit."],"exampleFix":"// before\nadd /Report/pivottable --prop source=Data!A1:Z5000 --prop position=XFC1\n// after\nadd /Report/pivottable --prop source=Data!A1:Z5000 --prop position=A1","handlingStrategy":"validation","validationCode":"// Conservatively check the pivot output fits within Excel bounds before Add.\nconst int ExcelMaxCol = 16384, ExcelMaxRow = 1048576;\nvar (anchorColStr, anchorRow) = ParseCellReference(position.ToUpperInvariant());\nint anchorColIdx = ColumnNameToIndex(anchorColStr);\nint nSourceCols = ColumnNameToIndex(srcEndCol) - ColumnNameToIndex(srcStartCol) + 1;\nint nDataRows = srcEndRow - srcStartRow;\nif (anchorColIdx + nSourceCols - 1 > ExcelMaxCol || anchorRow + nDataRows + 1 > ExcelMaxRow)\n    throw new InvalidOperationException($\"pivot at {position} does not fit within sheet bounds.\");","typeGuard":null,"tryCatchPattern":"try { handler.Add(parentPath, \"pivottable\", null, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not fit\"))\n{ /* move the anchor left/up or omit position for auto-placement, then retry */ }","preventionTips":["Default to auto-positioning (omit position) so the handler places the pivot after the source.","Avoid anchors near XFD or row 1048576 for wide/tall sources.","Compute the conservative end (anchor + source cols/rows) before fixing a position."],"tags":["excel","pivot-table","validation","sheet-bounds","positioning"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}