{"record":{"id":"b454c38a71e95656","repo":"iOfficeAI/OfficeCLI","slug":"anchor-cell-original-is-outside-excel-s-grid","errorCode":null,"errorMessage":"Anchor cell '{original}' is outside Excel's grid (A1..XFD1048576).","messagePattern":"Anchor cell '(.+?)' is outside Excel's grid \\(A1\\.\\.XFD1048576\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs","lineNumber":1597,"sourceCode":"    /// <summary>Swap anchor corners per axis so from ≤ to.</summary>\n    internal static void NormalizeAnchorRect(ref int fromCol, ref int fromRow, ref int toCol, ref int toRow)\n    {\n        if (toCol >= 0 && toCol < fromCol) (fromCol, toCol) = (toCol, fromCol);\n        if (toRow >= 0 && toRow < fromRow) (fromRow, toRow) = (toRow, fromRow);\n    }\n\n    /// <summary>\n    /// Bounds-check a parsed 0-based anchor cell against Excel's real grid\n    /// (A1..XFD1048576). Row 0 (A0) parses to -1 and columns past XFD wrap\n    /// into indices Excel refuses (0x800A03EC) while schema validation stays\n    /// green — reject at parse time instead.\n    /// </summary>\n    internal static void ValidateAnchorCell(int col0, int row0, string original)\n    {\n        const int MaxCol0 = 16383;      // XFD\n        const int MaxRow0 = 1048575;    // 1,048,576 rows, 0-based\n        if (col0 < 0 || col0 > MaxCol0 || row0 < 0 || row0 > MaxRow0)\n            throw new ArgumentException(\n                $\"Anchor cell '{original}' is outside Excel's grid (A1..XFD1048576).\");\n    }\n\n    /// <summary>\n    /// Clamp a TwoCellAnchor span computed from x/y/width/height (column/row\n    /// units) to Excel's grid. The FROM marker must be a real cell\n    /// (A1..XFD1048576) and still throws if outside it. The TO marker is the\n    /// exclusive right/bottom edge, so it may legitimately sit one past the last\n    /// cell (col 16384 / row 1048576) — a picture/shape placed near XFD simply\n    /// ends at the grid edge, which is what real Excel does. A width/height that\n    /// walks the TO marker further than that (e.g. x=1,width=16384 → toCol 16385)\n    /// was silently persisted and made Excel refuse the file (0x800A03EC), so the\n    /// TO marker is clamped to the ceiling here rather than written out of range.\n    /// Returns the clamped (toCol, toRow).\n    /// </summary>\n    internal static (int toCol, int toRow) ClampAnchorSpan(int fromCol, int fromRow, int toCol, int toRow, string original)\n    {\n        ValidateAnchorCell(fromCol, fromRow, original);","sourceCodeStart":1579,"sourceCodeEnd":1615,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs#L1579-L1615","documentation":"Thrown by ValidateAnchorCell when a parsed 0-based anchor cell falls outside Excel's real grid (A1..XFD1048576, i.e. col 0..16383, row 0..1048575). The check exists because Row 0 ('A0') parses to row index -1 and columns past XFD wrap into indices Excel refuses (0x800A03EC) while OOXML schema validation stays green - the parser rejects at parse time instead of persisting an unopenable file.","triggerScenarios":"Passing anchor='A0' (row 0 -> index -1), anchor='XFE1' (column past XFD), anchor='A1048577' (row past the 1048576 limit), or any cell reference whose parsed column/row is out of range. Triggered via the anchor= cell-reference/range path.","commonSituations":"Off-by-one errors in computed cell references; assuming 0-based rows in the reference string ('A0'); passing a column letter sequence past XFD; programmatic row/column overflow.","solutions":["Use a valid cell in A1..XFD1048576: anchor='B2'.","Remember Excel references are 1-based: the first row is '1', not '0'.","Clamp computed column index to [0, 16383] and row index to [0, 1048575] before formatting the reference.","Validate with a cell-reference parser and reject 'A0' / past-XFD columns upstream."],"exampleFix":"// before\nshape anchor=A0\n// after\nshape anchor=A1","handlingStrategy":"validation","validationCode":"// Excel grid: A1..XFD1048576 -> 0-based col [0,16383], row [0,1048575]\nconst int MaxCol0 = 16383, MaxRow0 = 1048575;\nbool IsValidAnchorCell(int col0, int row0)\n    => col0 >= 0 && col0 <= MaxCol0 && row0 >= 0 && row0 <= MaxRow0;\n\n// reject 'A0' (row 0 -> -1) and past-XFD columns before formatting the reference.","typeGuard":"static bool IsWithinExcelGrid(int col0, int row0)\n    => col0 >= 0 && col0 <= 16383 && row0 >= 0 && row0 <= 1048575;","tryCatchPattern":"try { ValidateAnchorCell(col0, row0, original); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"outside Excel's grid\"))\n{\n    // clamp col0/row0 into range, or surface a user error\n}","preventionTips":["Use cell references in A1..XFD1048576 only.","Remember Excel references are 1-based: the first row is '1', not '0'.","Clamp computed col to [0,16383] and row to [0,1048575] before formatting.","Reject 'A0' and columns past XFD upstream."],"tags":["excel","drawing","anchor","cell-reference","validation","grid-limit"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}