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 branchView on GitHub (pinned to 1ced45e900)
Solutions
- Ensure the anchor path references the same sheet as the parent path: '/<sheetName>/row[K]' where <sheetName> matches the parent.
- If you need to reference a row in a different sheet, use a copy/move operation instead of an insertion anchor.
- 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
- Ensure the anchor's sheet name matches the parent path's sheet.
- Parameterize both the parent sheet and the anchor from the same variable.
- For cross-sheet operations, use copy/move instead of insertion anchors.
- Avoid copy-pasting anchors from a different sheet's context.
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
- Anchor must be a row path like /{sheetName}/row[K], got: {an
- invalid_path
- unsupported_path
- Sheet not found: {sheetName}
- Unknown dataBar axisPosition '{dbAxisPos}'. Valid: automatic
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/d5d0bf15eba42721.
Report an issue: GitHub.