iOfficeAI/OfficeCLI · error · ArgumentException

Anchor sheet '{aSegs[0]}' must match target sheet '{sheetNam

Error message

Anchor sheet '{aSegs[0]}' must match target sheet '{sheetName}'

What it means

Thrown by FindAnchorRow when the anchor path's sheet segment does not match the target sheet (case-insensitive comparison). Row insertion anchors must reference the same sheet as the parent path — you cannot insert a row in Sheet1 anchored to a row in Sheet2. The comparison uses StringComparison.OrdinalIgnoreCase so only a genuine different-sheet mismatch triggers this, not a casing difference.

Source

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

        // Resolve --before / --after anchors (same shape as Excel CopyFrom):
        // anchor must be /<sheetName>/row[K] in the same sheet.
        // CONSISTENCY(zero-based-index): per project convention, position.Index
        // is 0-based across all formats (--index 0 = head, --index 1 = before
        // 2nd slot). xlsx Row uses a 1-based RowIndex internally, so +1 here
        // and let the existing branch keep treating `index` as a 1-based row
        // number (which is also what the anchor branch below produces).
        int? index = position?.Index.HasValue == true ? position!.Index!.Value + 1 : (int?)null;
        if (index == null && position != null && (position.After != null || position.Before != null))
        {
            int FindAnchorRow(string anchorPath)
            {
                var aSegs = anchorPath.TrimStart('/').Split('/', 2);
                if (aSegs.Length < 2)
                    throw new ArgumentException(
                        $"Anchor must be a row path like /{sheetName}/row[K], got: {anchorPath}");
                if (!aSegs[0].Equals(sheetName, StringComparison.OrdinalIgnoreCase))
                    throw new ArgumentException(
                        $"Anchor sheet '{aSegs[0]}' must match target sheet '{sheetName}'");
                var am = Regex.Match(aSegs[1], @"^row\[(\d+)\]$");
                if (!am.Success)
                    throw new ArgumentException(
                        $"Anchor must be a row path like /{sheetName}/row[K], got: {anchorPath}");
                return (int)uint.Parse(am.Groups[1].Value);
            }
            // For row insertion, --before /Sheet1/row[5] means "the new row
            // takes the row[5] slot, original row[5] shifts to row[6]". So
            // resolved index == anchor row number. --after /Sheet1/row[5]
            // means index == anchor + 1.
            if (position.Before != null) index = FindAnchorRow(position.Before);
            else index = FindAnchorRow(position.After!) + 1;
        }

        var rowIdx = index ?? ((int)(sheetData.Elements<Row>().LastOrDefault()?.RowIndex?.Value ?? 0) + 1);

        // Excel's row space tops out at 1048576 (2^20). The append branch

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Ensure the anchor path references the same sheet as the parent path: '/<sheetName>/row[K]' where <sheetName> matches the parent.
  2. If you need to reference a row in a different sheet, use a copy/move operation instead of an insertion anchor.
  3. Parameterize both the parent sheet name and the anchor sheet name from the same variable.

Example fix

// before: anchor sheet differs from target sheet
handler.Add("/Sheet1", "row", null, new { before = "/Sheet2/row[5]" }); // mismatch

// after: anchor in the same sheet
handler.Add("/Sheet1", "row", null, new { before = "/Sheet1/row[5]" });
Defensive patterns

Strategy: validation

Validate before calling

// Validate the anchor references the same sheet as the target
static bool IsSameSheetAnchor(string anchor, string targetSheet)
{
    var segs = anchor.TrimStart('/').Split('/', 2);
    return segs.Length >= 1 && segs[0].Equals(targetSheet, StringComparison.OrdinalIgnoreCase);
}

Try / catch

try
{
    handler.Add($"/{sheetName}", "row", new InsertPosition { Before = anchor }, properties);
}
catch (ArgumentException ex) when (ex.Message.Contains("must match target sheet"))
{
    // Anchor references a different sheet — fix the anchor or use a different operation
    logger.LogError("Anchor sheet '{AnchorSheet}' must match target '{Target}'.", anchor, sheetName);
    throw;
}

Prevention

When it happens

Trigger: Calling Add with parent path '/Sheet1' and a --before or --after anchor like '/Sheet2/row[5]'. The resolver extracts 'Sheet2' from the anchor and compares it to 'Sheet1' from the parent path; the mismatch is rejected because cross-sheet anchoring is not meaningful for row insertion.

Common situations: A copy-paste error where the anchor path was taken from a different sheet's context; a script that hardcodes the anchor sheet name while the parent sheet is parameterized; confusion when the parent path and anchor path are built from different sources.

Related errors


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