{"record":{"id":"9d9a00edf4d69447","repo":"iOfficeAI/OfficeCLI","slug":"row-break-index-rbidx-out-of-range-1-breaks-co","errorCode":null,"errorMessage":"Row break index {rbIdx} out of range (1-{breaks.Count})","messagePattern":"Row break index (.+?) out of range \\(1-(.+?)\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Query.cs","lineNumber":467,"sourceCode":"\n        // BUG-R41-F2: reject cell reference segments that contain control characters\n        // (e.g. \\n, \\r, \\t). Without this check, \"A1\\n\" passes the cell-ref regex\n        // (Regex `$` matches before trailing \\n in .NET) and resolves to a ghost cell.\n        var cellRef = segments[1];\n        if (cellRef.Any(c => c < ' ' && c != '\\t' || c == '\\x7f'))\n            throw new ArgumentException(\n                $\"Cell reference '{cellRef.Replace(\"\\n\", \"\\\\n\").Replace(\"\\r\", \"\\\\r\")}' contains invalid control characters. \" +\n                $\"Expected a clean cell address like 'A1' or 'B2'.\");\n\n        // Page break path: /Sheet1/rowbreak[N] or /Sheet1/colbreak[N]\n        var rbMatch = Regex.Match(cellRef, @\"^rowbreak\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n        if (rbMatch.Success)\n        {\n            var rbIdx = int.Parse(rbMatch.Groups[1].Value);\n            var rowBreaks = GetSheet(worksheet).GetFirstChild<RowBreaks>();\n            var breaks = rowBreaks?.Elements<Break>().ToList() ?? new();\n            if (rbIdx < 1 || rbIdx > breaks.Count)\n                throw new ArgumentException($\"Row break index {rbIdx} out of range (1-{breaks.Count})\");\n            var brk = breaks[rbIdx - 1];\n            var rbNode = new DocumentNode\n            {\n                Path = path, Type = \"rowbreak\",\n                Format = { [\"row\"] = brk.Id?.Value ?? 0u, [\"manual\"] = brk.ManualPageBreak?.Value ?? false }\n            };\n            // Restricted-span page break (<brk min max>): surface a non-default\n            // column span so dump→replay reproduces it. Full-width default\n            // (min 0 / max 16383) is omitted to keep the readback clean.\n            if (brk.Min?.Value is { } rbMin && rbMin > 0) rbNode.Format[\"min\"] = (int)rbMin;\n            if (brk.Max?.Value is { } rbMax && rbMax != 16383u) rbNode.Format[\"max\"] = (int)rbMax;\n            return rbNode;\n        }\n        var cbMatch = Regex.Match(cellRef, @\"^colbreak\\[(\\d+)\\]$\", RegexOptions.IgnoreCase);\n        if (cbMatch.Success)\n        {\n            var cbIdx = int.Parse(cbMatch.Groups[1].Value);\n            var colBreaks = GetSheet(worksheet).GetFirstChild<ColumnBreaks>();","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Query.cs#L449-L485","documentation":"Thrown for /SheetName/rowbreak[N] when N is outside the 1-based range [1, <rowBreaks.Count>]. Row breaks (manual horizontal page breaks) live in the worksheet's <rowBreaks> element; if there are none the valid range is 1-0 and any index is rejected, including rowbreak[0].","triggerScenarios":"handler.Get(\"/Sheet1/rowbreak[3]\") on a sheet with fewer than 3 manual row page breaks, or rowbreak[1] on a sheet with no row breaks at all. Using a 0-based index (rowbreak[0]).","commonSituations":"Assuming a sheet has page breaks because it was imported from a print-formatted workbook. Off-by-one from zero-based indexing. Hard-coded break indices after the file was edited and breaks removed.","solutions":["Confirm the sheet actually has manual row breaks before indexing.","Use a 1-based index within [1, count]; there is no index 0.","Wrap Get in try/catch(ArgumentException) and read the valid range from the message."],"exampleFix":"// before\nvar rb = handler.Get(\"/Sheet1/rowbreak[3]\"); // throws if <3 breaks\n\n// after\nDocumentNode? GetRowBreak(ExcelHandler h, string sheet, int n) {\n  try { return h.Get($\"/{sheet}/rowbreak[{n}]\"); }\n  catch (ArgumentException) { return null; }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"static int? ElementIndex(string cellRef, string element)\n{\n    var m = Regex.Match(cellRef, $@\"^{Regex.Escape(element)}\\[(\\d+)$\", RegexOptions.IgnoreCase);\n    return m.Success && int.TryParse(m.Groups[1].Value, out var i) ? i : null;\n} // shape/1-based check only — not a range check","tryCatchPattern":"try { return handler.Get($\"/{sheet}/rowbreak[{n}]\"); }\ncatch (ArgumentException ex) { /* ex.Message carries the valid 1-N range */ return null; }","preventionTips":["All element indices are 1-based — there is no index 0.","Don't assume a sheet has manual page breaks; confirm before indexing.","Parse the valid range out of the exception message for a clear retry bound."],"tags":["excel","page-breaks","rowbreak","path-index","argument-exception"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}