iOfficeAI/OfficeCLI · error · ArgumentException

Row {rowIdx} not found

Error message

Row {rowIdx} not found

What it means

Thrown during a row move when row[N] does not resolve: it is out of ordinal range (N > row count) AND no <Row> element has RowIndex == N. Lookup tries ordinal (Nth row element) then falls back to matching the stored RowIndex, so a genuinely absent row fails.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.cs:301

        else
        {
            var tgtSegments = targetParentPath.TrimStart('/').Split('/', 2);
            var tgtWorksheet = FindWorksheet(tgtSegments[0])
                ?? throw new ArgumentException($"Target sheet not found: {tgtSegments[0]}");
            targetSheetData = GetSheet(tgtWorksheet).GetFirstChild<SheetData>()
                ?? throw new ArgumentException("Target sheet has no data");
        }

        // Find and move the row
        var rowMatch = Regex.Match(elementRef, @"^row\[(\d+)\]$");
        if (rowMatch.Success)
        {
            var rowIdx = int.Parse(rowMatch.Groups[1].Value);
            // Try ordinal lookup first (Nth row element), then fall back to RowIndex
            var allRows = sheetData.Elements<Row>().ToList();
            var row = (rowIdx >= 1 && rowIdx <= allRows.Count ? allRows[PathIndex.ToArrayIndex(rowIdx)] : null)
                ?? sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex?.Value == (uint)rowIdx)
                ?? throw new ArgumentException($"Row {rowIdx} not found");

            // Resolve --before / --after anchors to a 0-based document-order
            // position in the target sheet. Anchor must be /<TargetSheet>/row[K].
            // Resolved BEFORE removing the moved row so the anchor is found by
            // its current position.
            int? targetIndex = index;
            string targetSheetName = string.IsNullOrEmpty(targetParentPath)
                ? sheetName
                : targetParentPath.TrimStart('/').Split('/', 2)[0];
            if (targetIndex == null && position != null && (position.After != null || position.Before != null))
            {
                int FindAnchorRowPos(string anchorPath)
                {
                    var aSegs = anchorPath.TrimStart('/').Split('/', 2);
                    if (aSegs.Length < 2)
                        throw new ArgumentException(
                            $"Anchor must be a row path like /{targetSheetName}/row[K], got: {anchorPath}");
                    if (!aSegs[0].Equals(targetSheetName, StringComparison.OrdinalIgnoreCase))

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Query the sheet's actual rows first (handler.Get("/Sheet1")) to see which indices exist.
  2. Use the ordinal count, not the spreadsheet's visual row number, when picking N.
  3. If the row is genuinely missing, insert it (Add row) before moving.

Example fix

// before
h.Move("/Sheet1/row[50]", null, null); // only 10 rows stored -> throws
// after
var rows = h.Get("/Sheet1", depth:2).Children.Where(c => c.Type == "row").ToList();
h.Move($"/Sheet1/row[{rows.Count}]", null, InsertPosition.AtIndex(1)); // move last real row
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the requested row index is actually stored.
var m = System.Text.RegularExpressions.Regex.Match(elementRef, @"^row\[(\d+)\]$");
var rowIdx = int.Parse(m.Groups[1].Value);
var rows = handler.Get(sheetName, depth: 2).Children.Where(c => c.Type == "row").ToList();
if (rowIdx < 1 || rowIdx > rows.Count) // ordinal check mirrors the handler's first attempt
    throw new InvalidOperationException($"Row {rowIdx} not present (have {rows.Count} rows)");

Type guard

static bool IsRowIndex(int n, int rowCount) => n >= 1 && n <= rowCount;

Try / catch

try { handler.Move($"/{sheet}/row[{n}]", target, pos); }
catch (ArgumentException ex) when (ex.Message.Contains("not found"))
{ /* enumerate real rows and retry with a valid index */ }

Prevention

When it happens

Trigger: Move("/Sheet1/row[999]") when the sheet has fewer rows; referencing a row index that was deleted; 1-based confusion where the user expected a sparse row that is not stored.

Common situations: Off-by-one on the 1-based index; row removed in a prior edit; assuming every row up to the used range is materialized (Excel omits empty rows).

Related errors


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